面向对象的 SOLID 原则

面向对象的 SOLID 原则

SOLID 原则是面向对象 class 设计的五条原则

由 Robert C · Martin 提出的,其著作有 《代码整洁之道》《架构整洁之道》

其目标是一致的:

创建可多人协作的、易于理解的、易读的以及可测试的代码

依次看一下 SOLID 原则:

  • S 职责单一原则
  • O 开闭原则
  • L 里式替换原则
  • I 接口隔离原则
  • D 依赖倒置原则

SRP (Single Responsibility Principle)

职责单一原则——软件设计的低耦合、高内聚,提高内聚性来减少引起变化的原因

核心思想:一个 Class 只做一件事情,并把这件事做好,其只有一个引起其变化的原则(职责变化)

因此,减少各个模块的依赖,确保一个 Class 只做一种工作。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class User(object):
def create():
pass

def delete():
pass

def update_info():
pass

class Book(object):
def add():
pass

def show():
pass

OCP (Open/Closed Principle)

开闭原则

核心思想:模块是可扩展的,而不可修改的

当存在已有模块方法时,对于新的需求或者变化时,可以对现有代码进行扩展,以适应新的情况。

对修改封闭,意味着一旦设计完成,就可以独立完成一些需求,而不要对类进行修改

当然,对于重构而言,该原则可适当调整。(随机应变)

LSP (Liskov substation Principle)

里氏代换原则

Rober C. Martin 将该原则最终简化为: Subtypes must be subsititutable for theire bases types——子类必须能够替换成它们的父类

  • 子类可以替换成它们的父类,并且经过替换之后,代码还能正常工作

  • 在代码中,不应该出现 if/else 之类来对子类类型进行判断的条件。

  • LSP 原则是使代码符合开闭原则的一个重要保证,正是由于子类的可替换性才使得父类的模块在无需修改的情况下就可以扩展。

LSP 原则其实对应 Python 中的继承和多态,即子类可以继承父类的属性和方法,子类也可以修改并扩展父类;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age

def eat():
pass

def sleep():
pass

class Dog(Animal):
def sing():
print("wangwang")
def sleep():
print("sleep")

ISP (Interface Segregation Principle)

接口隔离原则

核心思想:使用专门的接口,而不是单一的总接口,即客户端不应该依赖那些它不需要的接口

例如:总接口 Animal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from abc import ABCMeta, abstractmethod

class Animal(metacalss=ABCMeta):
@abstractmethod
def walk(self):
pass

@abstractmethod
def swim(self):
pass

@abstractmethod
def fly(self):
pass

但是,并不是所有的 Animal 都会飞,游泳,于是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class WalkAnimal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def walk(self):
print("walking...")


class SwimAnimal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def swim(self):
pass


class FlyAnimal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def fly(self):
pass

DIP (Dependency Inversion Principle)

依赖倒置原则

高层模块不应该依赖于低层模块的实现,而是依赖于高层抽象。

冰箱的开关不应该依赖于电灯的开关实现,而是依赖于一个抽象的开关标准接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import abc


class Switch(metaclass=abc.ABCMeta):
@abc.abstractmethod
def on(self):
pass

@abc.abstractmethod
def off(self):
pass


class Light(Switch):

def on(self):
print("light on")

def off(self):
print("light off")


class Refrigerator(Switch):
def on(self):
print("refrigerator on")

def off(self):
print("refrigerator off")

参考

https://www.freecodecamp.org/chinese/news/solid-principles/

https://www.51cto.com/article/667555.html

https://blog.csdn.net/weixin_51098806/article/details/123908651

-------------THANKS FOR READING-------------