设计模式:软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。
面向对象三大特性:封装、继承、多态。
面向对象设计的SOLID原则:
(1)开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
(2)里氏替换原则:所有引用父类的地方必须能透明地使用其子类的对象。
(3)依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象; 抽象不应该依赖细节;细节应该依赖抽象。
(4)接囗隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
(5)单一职责原则:不要存在多于一个导致类变更的原因,即一个类只负责一项职责。
举个例子,可能有不止一块代码调用到该实体,这时候去修改实体里的代码,就很可能引起其他模块会出现问题,当模块关联较多时就会引起不必要的工作量,这是1;
原方法支持父类,当我们在基础上加或修改功能而衍生的子类也应当符合,这是2;
要针对接口编程, 而不是针对实现编程,实现上也就是对底层的依赖按接口格式去写,再实现,而不是随意修改参数格式,即3。
简单工厂模式,工厂方法模式,抽象工厂模式,创建者模式,原型模式,单例模式。
创建型模式(Creational Pattern) | 一种用于 创建对象 的设计模式。它们包含一些通用的方法,更加灵活地创建对象,且 封装 了对象的实例化过程 |
工厂模式(Factory Pattern) | 用于根据 客户端需求动态创建 对象。 (包括简单工厂模式,工厂方法模式,抽象工厂模式) |
单例模式(Singleton Pattern) | 用于确保一个类 只有一个 实例,并提供对该实例的全局访问点。它通常被用于管理共享资源或者限制系统中某些类的实例数量。 |
建造者模式(Builder Pattern) | 用于将一个复杂对象的 构建过程分离 成多个简单的步骤,从而可以灵活地组合和构建不同的对象。它通常被用于创建复杂的对象,比如包含多个组件或者配置项的对象。 |
原型模式(Prototype Pattern) | 用于 复制或克隆 已有的对象,从而创建新的对象。它通过克隆现有对象来创建新对象,从而避免了昂贵的初始化操作。 |
简单工厂模式(Simple Factory Pattern):简单工厂模式是一种基本的工厂模式,通常由一个工厂类根据传入的参数动态决定创建哪种产品类的实例。(简单而言:一个工厂类根据传入参数创建哪个类实例) 场景:适用于对象较少且产品等级结构稳定的情况。 Characters: 工厂角色(Factory) 抽象产品角色(Product) 具体产品角色(Concrete Product)
- class Product:
- def use(self):
- pass
-
-
- class ConcreteProductA(Product):
- def use(self):
- print("Using product A.")
-
-
- class ConcreteProductB(Product):
- def use(self):
- print("Using product B.")
-
-
- class Factory:
- @staticmethod
- def create_product(product_type):
- if product_type == "A":
- return ConcreteProductA()
- elif product_type == "B":
- return ConcreteProductB()
-
-
- product_a = Factory.create_product("A")
- product_a.use() # 输出:Using product A.
-
- product_b = Factory.create_product("B")
- product_b.use() # 输出:Using product B.
工厂方法模式(Factory Method Pattern):将实际创建对象的工作推迟到子类中完成。可以在不修改工厂类的情况下,增加新的产品系列和产品等级结构。(简单而言:工厂类抽象化,将增改操作下发给子类) 场景: 工厂方法模式适用于对象数量较多且产品等级结构较为复杂的情况。 Characters: 工厂角色(Factory) 具体工厂角色(Concrete Factory) 抽象产品角色(Product) 具体产品角色(Concrete Product)
- class Product:
- def use(self):
- pass
-
-
- class ConcreteProductA(Product):
- def use(self):
- print("Using product A.")
-
-
- class ConcreteProductB(Product):
- def use(self):
- print("Using product B.")
-
-
- class Factory:
- def create_product(self):
- pass
-
-
- class ConcreteFactoryA(Factory):
- def create_product(self):
- return ConcreteProductA()
-
-
- class ConcreteFactoryB(Factory):
- def create_product(self):
- return ConcreteProductB()
-
-
- factory_a = ConcreteFactoryA()
- product_a = factory_a.create_product()
- product_a.use() # 输出:Using product A.
-
- factory_b = ConcreteFactoryB()
- product_b = factory_b.create_product()
- product_b.use() # 输出:Using product B.
抽象工厂模式(Abstract Factory Pattern):是一种将工厂类进行抽象化的进一步改进,它使用了对象组合的方式来构建不同的产品族。(工厂抽象化,组合各种产品,有点像工厂方法模式的不同类方法组合)
场景: 抽象工厂模式可以同时创建多个不同的产品,且这些产品之间存在着一定的关联性。
Characters: 工厂角色(Factory) 具体工厂角色(Concrete Factory) 抽象产品角色(Product) 具体产品角色(Concrete Product) 客户端(Client)
- class ProductA:
- def use(self):
- pass
-
-
- class ConcreteProductA1(ProductA):
- def use(self):
- print("Using product A1.")
-
-
- class ConcreteProductA2(ProductA):
- def use(self):
- print("Using product A2.")
-
-
- class ProductB:
- def operate(self):
- pass
-
-
- class ConcreteProductB1(ProductB):
- def operate(self):
- print("Operating product B1.")
-
-
- class ConcreteProductB2(ProductB):
- def operate(self):
- print("Operating product B2.")
-
-
- class Factory:
- def create_product_a(self):
- pass
-
- def create_product_b(self):
- pass
-
-
- class ConcreteFactory1(Factory):
- def create_product_a(self):
- return ConcreteProductA1()
-
- def create_product_b(self):
- return ConcreteProductB1()
-
-
- class ConcreteFactory2(Factory):
- def create_product_a(self):
- return ConcreteProductA2()
-
- def create_product_b(self):
- return ConcreteProductB2()
-
-
- factory_1 = ConcreteFactory1()
- product_a1 = factory_1.create_product_a()
- product_a1.use() # 输出:Using product A1.
- product_b1 = factory_1.create_product_b()
- product_b1.operate() # 输出:Operating product B1.
-
- factory_2 = ConcreteFactory2()
- product_a2 = factory_2.create_product_a()
- product_a2.use() # 输出:Using product A2.
- product_b2 = factory_2.create_product_b()
- product_b2.operate() # 输出:Operating product B2.
保证一个类仅有一个实例,并提供访问该实例的全局访问点。
- class Singleton:
- __instance = None
-
- def __new__(cls):
- if cls.__instance is None:
- cls.__instance = object.__new__(cls)
- return cls.__instance
-
-
- s1 = Singleton()
- s2 = Singleton()
- print(s1 is s2) # 输出:True =》 说明唯一性
将一个复杂对象的构建过程分离成多个简单的步骤 场景: 灵活地组合和构建不同的对象。 Characters: 产品类(Product) 抽象建造者类(Builder) 具体建造者类(ConcreteBuilder) 指挥者类(Director)
- class Product:
- def __init__(self):
- self.part_a = None
- self.part_b = None
-
-
- class Builder:
- def build_part_a(self):
- pass
-
- def build_part_b(self):
- pass
-
- def get_result(self):
- pass
-
-
- class ConcreteBuilder1(Builder):
- def __init__(self):
- self.product = Product()
-
- def build_part_a(self):
- self.product.part_a = "Part A1"
-
- def build_part_b(self):
- self.product.part_b = "Part B1"
-
- def get_result(self):
- return self.product
-
-
- class ConcreteBuilder2(Builder):
- def __init__(self):
- self.product = Product()
-
- def build_part_a(self):
- self.product.part_a = "Part A2"
-
- def build_part_b(self):
- self.product.part_b = "Part B2"
-
- def get_result(self):
- return self.product
-
-
- class Director:
- def __init__(self, builder):
- self.builder = builder
-
- def construct(self):
- self.builder.build_part_a()
- self.builder.build_part_b()
-
- return self.builder.get_result()
-
-
- builder_1 = ConcreteBuilder1()
- director_1 = Director(builder_1)
- product_1 = director_1.construct()
- print(f"Product 1: {product_1.part_a}, {product_1.part_b}") # 输出:Product 1: Part A1, Part B1
-
- builder_2 = ConcreteBuilder2()
- director_2 = Director(builder_2)
- product_2 = director_2.construct()
- print(f"Product 2: {product_2.part_a}, {product_2.part_b}") # 输出:Product 2: Part A2, Part B2
允许通过复制现有对象来创建新的对象,而无需重新实例化。 Think: 定义一个抽象原型类,包含了用于复制自身的抽象方法 clone()。然后,定义具体的原型类。在客户端代码中,可以通过调用具体对象 clone() 方法来创建新的对象,而无需重新实例化。(注意深浅拷贝问题)
- import copy
-
-
- class Prototype:
- def clone(self):
- return copy.deepcopy(self)
-
-
- class ConcretePrototype1(Prototype):
- def __init__(self, attr):
- self.attr = attr
-
-
- class ConcretePrototype2(Prototype):
- def __init__(self, attr):
- self.attr = attr
-
-
- if __name__ == '__main__':
- prototype_1 = ConcretePrototype1("attr_1")
- prototype_2 = ConcretePrototype2("attr_2")
-
- clone_1 = prototype_1.clone()
- clone_2 = prototype_2.clone()
-
- print(f"Original: ({prototype_1.attr}, {prototype_2.attr})") # 输出:Original: (attr_1, attr_2)
- print(f"Clone: ({clone_1.attr}, {clone_2.attr})") # 输出:Clone: (attr_1, attr_2)