点击上方”python宝典”,关注获取python全套视频,
技术文章第一时间送达!
一、什么是设计模式
每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。” 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。 GoF(Gang of Four) 设计模式四个基本要素:模式名称、问题、解决方案、效果
二、设计模式七大原则
1、开放封闭原则:一个软件实体如类,模块和函数应该对扩展是开放的,对修改是关闭的。即软件实体应尽量在不修改原有代码的情况下进行扩展(装饰器)
2、里氏替换原则:重写父类里面的方法,逻辑可能不一样,但是返回的结果参数啥的要一样(所有引用基类的地方必须能透明的使用其子类的对象)
3、依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象,要针对接口编程,而不是针对实现编程。(接口类)
4、接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要实现的接口
5、迪米特法则:一个软件实体应当尽可能少的与其他实体发生相互作用
6、单一职责原则:一个类只负责一项职责(不要存在多于一个导致类变更的原因,即一个类只负责一项职责)
7、合同复用原则:多用组合少用继承
一个类重用另一个类的代码有两种方式
a、下面来说一下接口隔离原则
接口隔离原则
#假如说现在有这样的动物类
from abc import abstractmethod,ABCMeta #借助abc模块来实现接口
#接口类就是为了提供标准,约束后面的子类
# class Animal(metaclass=ABCMeta):
# @abstractmethod
# def walk(self):
# pass
#
# @abstractmethod
# def fly(self):
# pass
#
# @abstractmethod
# def swim(self):
# pass
#
# class Frog(Animal):
# '''像是这样定义一个青蛙类,由于接口类的方法都要被实现,而青蛙只会走,没不要要实现其他的方法
# 动物不同会的功能也会不同,所以这时候我们就可以选择用接口隔离原则
# '''
# def walk(self):
# print('青蛙会走')
#
# obj = Frog()
# obj.walk() #会报错
# =====================改进-=================
class AnimalOnLand(metaclass=ABCMeta):
'''在陆地上的动物'''
@abstractmethod
def walk(self):
pass
class AnimalInSky(metaclass=ABCMeta):
'''飞行动物'''
@abstractmethod
def fly(self):
pass
class AnimalInWater(metaclass=ABCMeta):
'''在水里的动物'''
@abstractmethod
def swim(self):
pass
class Tiger(AnimalOnLand):
def walk(self):
print('老虎在地上')
class Frog(AnimalOnLand,AnimalInWater):
def swim(self):
print('青蛙会游')
def walk(self):
print('会跳')
obj = Tiger()
obj.walk()
obj = Frog()
obj.walk()
obj.swim()
b、继承和组合
# 合同复用原则:多用组合少用继承
class A:
def test(self):
return '你好啊'
class B(A): #继承
def test(self):
return 123
class C:
def __init__(self):
self.a = A() #组合
self.a.test()
def test(self):
return 789
print(B().test())
print(C().a)
print(C().a.test())
print(C().test())
三、设计模式分类
创建型模式:
总结创建型模式:
依赖于继承的创建型模式:工厂方法模式
依赖于组合的创建型模式:抽象工厂模式,创建者模式
行为型模式:
结构性模式:
四、简单工厂模式
1、内容
不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
2、角色
3、优点
4、缺点
5、使用场景
强调一系列相关的产品对象的设计以便进行联合使用时
6、代码示例
原始的
from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self):
pass
class Alipay(Payment):
def __init__(self,money):
self.money = money
def pay(self):
print('支付宝支付了%s元'%self.money)
class Whatpay(Payment):
def __init__(self, money):
self.money = money
def pay(self):
print('微信支付了%s元' % self.money)
obj = Alipay(100)
obj.pay()
obj2 = Whatpay(200)
obj2.pay()
简单工厂
from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self,money):
pass
class Alipay(Payment):
def pay(self, money):
print('支付宝支付了%s元'%money)
class Applepay(Payment):
def pay(self, money):
print('微信支付了%s元' %money)
class Yuebao(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()
elif method =='yuebao':
return Yuebao()
else:
return NameError(method)
factory = PaymentFactory()
alipay=factory.create_payment('yuebao')
alipay.pay(100)
五、工厂方法模式
1、内容
定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类
2、角色
工厂方法模式相比简单工厂模式将每个具体产品都对应一个具体工厂
3、优点
4、缺点
5、使用场景
6、代码示例
from abc import ABCMeta,abstractmethod
class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self,money):
pass
class Alipay(Payment):
def pay(self, money):
print('支付宝支付了%s元'%money)
class Applepay(Payment):
def pay(self, money):
print('微信支付了%s元' %money)
class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()
class AppleFactory(PaymentFactory):
def create_payment(self):
return Applepay()
apple = AppleFactory()
apple.create_payment().pay(100)
alipay = AlipayFactory()
alipay.create_payment().pay(300)
#输出
# 微信支付了100元
# 支付宝支付了300元
六、抽象工厂模式
1、内容
定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象
例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
2、角色
相比工厂方法模式,抽象工厂模式中的每个具体工厂都产生一套产品
3、优点
4、缺点
5、使用场景
6、代码示例
from abc import abstractmethod,ABCMeta
#==============抽象产品============
class PhoneShell(metaclass=ABCMeta):
'''手机壳'''
@abstractmethod
def show_shell(self):
pass
class CPU(metaclass=ABCMeta):
'''CPU'''
@abstractmethod
def show_cpu(self):
pass
class OS(metaclass=ABCMeta):
'''操作系统'''
@abstractmethod
def show_os(self):
pass
# ===============抽象工厂==============
class PhoneFactory(metaclass=ABCMeta):
@abstractmethod
def make_shell(self):
'''制作手机壳'''
pass
@abstractmethod
def make_cpu(self):
'''制作cpu'''
pass
@abstractmethod
def make_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 YingTeerCPU(CPU):
def show_cpu(self):
print('英特尔cpu')
class MediaCPU(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系统')
class IOS(OS):
def show_os(self):
print('ios系统')
# ==============具体工厂================
class MiFactory(PhoneFactory):
def make_shell(self):
return SmallShell()
def make_cpu(self):
return AppleCPU()
def make_os(self):
return Android()
class HuaWeiactory(PhoneFactory):
def make_shell(self):
return BigShell()
def make_cpu(self):
return YingTeerCPU()
def make_os(self):
return Android()
# ===============使用===============
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(HuaWeiactory())
p1.show_info()
p2 = make_phone(MiFactory())
p2.show_info()
识别图中二维码,欢迎关注python宝典