设计模式六大原则:
1.开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改封闭。即软件实体应尽量在不修改原有代码的情况下进行扩展
2.里氏替换原则:所有引用基类(父类)的地方必须能透明的使用其子类的对象。
3.依赖倒置原则:高层模块不应该依赖底层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该抽象。换言之,要针对接口编程,而不是针对实现编程。
4.接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
5.迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
6.单一职责原则:不要存在多于一个导致类变更的原因。通俗地说,即一个类只负责一项职责。
设计模式分类:
1.创建型模式
单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点。
适用场景:当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
优点:a.对唯一实例的受控访问
b.单例相当于全局变量,但防止了命名空间被污染
与单例模式功能相似的概念:全局变量、静态变量(方法)
class Singleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): cls._instance = super(Singleton, cls).__new__(cls) return cls._instance class MyClass(Singleton): def __init__(self): self.name = name a = MyClass("a") print(a) print(a.name) b = MyClass("b") print(b) print(b.name) #返回的结果都是相同的内存地址,说明是一个对象
简单工厂模式
from abc import abctractmethod, ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): raise NotImplementedError class Alipay(Payment): def pay(self, money): print("支付宝支付%s元" % money) class ApplePay(Payment): def pay(self, money): print("苹果支付%s元" % money) class PaymentFactory: def create_payment(self, method): if method == "alipay": return Alipay() elif method == "applepay": return ApplePay() else: raise NameError(method) f = PaymentFactory() p = f.create_payment("alipay") p.pay(100) #支付宝支付100元 #f = PaymentFactory() #p = f.create_payment("applepay") #p.pay(100) #苹果支付100元
工厂方法模式:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类 工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。 适用场景: 1.需要生产多种、大量复杂对象的时候 2.需要降低耦合度的时候 3.当系统中的产品种类需要经常扩展的时候 优点: 1.每个具体产品都对应一个具体工厂类,不需要修改工厂类代码 2.隐藏了对象创建的实现细节 缺点:每增加一个具体产品类,就必须增加一个相应的具体工厂类
from abc import abstractmethod, ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass class Alipay(Payment): def pay(self, money): print("支付宝支付%元" % money) class ApplePay(Payment): def pay(self, money): print("苹果支付%s元" % money) class PaymentFactory(metaclass=ABCMeta): @abstractmethod def create_payment(self): pass class AlipayFactory(PaymentFactory): def create_payment(self): return Alipay() class ApplePayFactory(PaymentFactory): def create_payment(self): return ApplePay() af = AlipayFactory() ali = af.create_payment() ali.pay(120)
抽象工厂模式:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象 例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂分别生产一部手机所需要的三个对象。 角色: 1.抽象工厂角色 2.具体工厂角色 3.抽象产品角色 4.具体产品角色 5.客户端 相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品 适用场景: 1.系统要独立于产品的创建与组合时 2.强调一系列相关的产品对象的设计以便进行联合使用时 3.提供一个产品类库,想隐藏产品的具体实现时 优点: 1.将客户端与类的具体实现相分离 2.每个工厂创建了一个完整的产品系列,使得易于交换产品系列 3.有利于产品的一致性(即产品之间的约束关系) 缺点:难以支持新种类的(抽象)产品
from abc import abstractmethod, ABCMeta #抽象产品 class PhoneShell(metaclass=ABCMeta): @abstractmethod def show_shell(self): pass class CPU(metaclass=ABCMeta): @abstractmethod def show_cpu(self): pass class OS(metaclass=ABCMeta): @abstractmethod def show_os(self): pass #具体产品 class SmallShell(PhoneShell): def show_shell(self): print('普通手机小手机壳') class BigShell(PhoneShell): def show_shell(self): print('普通手机大手机壳') class AppleShell(PhoneShell): def show_shell(self): print('苹果手机壳') class SnapDragonCPU(CPU): def show_cpu(self): print('骁龙CPU') class MediaTekCPU(CPU): def show_cpu(self): print('联发科CPU') class AppleCPU(CPU): def show_cpu(self): print('苹果CPU') class Android(OS): def show_os(self): print('Android系统') classIOS(OS): def show_os(self): print('ios系统') #抽象工厂 class PhoneFactory(metaclass=ABCMeta): @abstractmethod def make_shell(self): pass @abstractmethod def make_cpu(self): pass @abstractmethod def make_os(self): pass #具体工厂 class MiFactory(PhoneFactory): def make_cpu(self): return SnapDragonCPU() def make_os(self): return Android() def make_shell(self): return BigShell() class HuaweiFactory(PhoneFactory): def make_cpu(self): return MediaTekCPU() def make_os(self): return Android() def make_shell(self): return SmallShell() class IPhoneFactory(PhoneFactory): def make_cpu(self): return AppleCPU() def make_os(self): return IOS() def make_shell(self): return AppleShell() #客户端 class Phone: def __init__(self, cpu, os, shell): self.cpu = cpu self.os = os self.shell = shell def show_info(self): print("手机信息:") self.cpu.show_cpu() self.os.show_os() self.shell.show_shell() def make_phone(factory): cpu = factory.make_cpu() os = factory.make_os() shell = factory.make_shell() return Phone(cpu, os, shell) p1 = make_phone(MiFactory()) p1.show_info()
建造者模式:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。 角色: 1.抽象建造者 2.具体建造者 3.指挥者 4.产品 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象 适用场景: 1.当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时 2.当构造过程允许被构造的对象有不同的表示时 优点: 1.隐藏了一个产品的内部结构和装配过程 2.将构造代码与表示代码分开 3.可以对构造过程进行更精细的控制
from abc import abstractmethod,ABCMeta #产品 class Player: def __init__(self, face=None, body=None, arm=None, leg=None): self.face = face self.arm = arm self.leg = leg self.body = body def __str__(self): return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg) #建造者 class PlayerBuilder(metaclass=ABCMeta): @abstractmethod def build_face(self): pass @abstractmethod def build_arm(self): pass @abstractmethod def build_leg(self): pass @abstractmethod def build_body(self): pass @abstractmethod def get_player(self): pass class BeautifulWomanBuilder(PlayerBuilder): def __init__(self): self.player = Player() def build_face(self): self.player.face = "漂亮脸蛋" def build_arm(self): self.player.arm = "细胳膊" def build_body(self): self.player.body = "细腰" def build_leg(self): self.player.leg = "长腿" def get_player(self): return self.player class PlayerDirector:
2.结构性模式
3.行为型模式