【python】之设计模式【未完】

前言

第1章 简介

1.1 面向对象相关

1.2 面相对象的3个设计设计原则

第2章–单例设计模式【创建型模式】

2.1 理解单例1

2.1.1实现单例 –代码解读

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
# 单例模式
class Singleton(object):
def __new__(cls): # __new__是在实例化的时候调用的方法
""" 判断cls类是否具有instance实例属性,如果没有就创建一个实例出来"""
if not hasattr(cls, 'instance'): # 如果cls类本身 没有实例
"""
这里比较难理解,
super(Singleton, cls)会返回Singleton类的父类object的对象
super(Singleton, cls).__new__(cls)也就是父类object的对象的__new__方法,
用父类的对象创建一个对象传递给cls(本类)
然后本类cls.instance就=父类对象创建出来的对象,
"""
cls.instance = super(Singleton, cls).__new__(cls) # 那类的实例就等于

return cls.instance # 如果有就直接返回这个实例cls.instance类的实例

s = Singleton()
print("Object created", s) # Object created <__main__.Singleton object at 0x7ffbc212fbe0>

s1 = Singleton()
print("Object created", s1) # Object created <__main__.Singleton object at 0x7ffbc212fbe0>
# 在 Python 中,对象的实例化过程包括两个步骤:__new__() 和 __init__()。__new__() 方法负责创建实例对象,而 __init__() 方法负责初始化实例。
# 在这个代码段中,super(Singleton, cls).__new__(cls) 使用了 super() 内置函数来调用父类 object 的 __new__() 方法。通过传递 Singleton 类和 cls 参数,super(Singleton, cls) 返回了一个代表父类的特殊对象。

# 然后,通过调用 __new__() 方法,父类 object 创建了一个新的实例对象。这个新的实例对象是通过传递 cls 参数(即 Singleton 类本身)给 __new__() 方法来创建的。

# 最后,将这个新创建的实例对象赋值给类属性 instance,以便后续的调用可以返回同一个实例。

# 换句话说,这行代码的目的是在首次实例化时创建一个新的实例,并将其赋值给类属性 instance,以便后续的实例化都返回该实例。

问:如何实现单例模式:

答:通过在定义类魔法方法__–new–__里面,做一个判断,判断 当前类是否存在实例化对象也就是cls.instance 如果有,就直接返回这个实例化对象,如果没有则通过super调用父类的new方法来创建一个实例 cls.instance = super(Singleton, cls).new(cls)) 然后再返回出去

UML类图简单学习笔记

设计模式三大类—>创建型、结构型、行为型

创建型

怎么去创建一个对象, 工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式

工厂模式

简单工厂模式

不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
"""
python设计模式之工厂模式
不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例
"""
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass


class Alipay(Payment):
def __init__(self, us_huabei=False):
self.us_huabei = us_huabei

def pay(self, money):
if self.us_huabei:
print(f"花呗支付{money}元")
else:
print(f"支付宝支付{money}元")


class WechatPay(Payment):
def pay(self, money):
print(f"微信支付{money}元")


class PaymentFactory:
def create_payment(self, method):
if method == "alipay":
return Alipay()
elif method == "wechatpay":
return WechatPay()
elif method == "huabei":
return Alipay(us_huabei=True)
else:
raise TypeError(f"no such payment named {method}")


if __name__ == '__main__':
pf = PaymentFactory()
p = pf.create_payment(method="alipay")
p.pay(100)

类不直接实例化,由工厂类去返回对应的实例化对象

工厂方法模式

工厂方法模式

优点:

  • 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
  • 隐藏了对象创建的实现细节3

缺点:

  • 每增加一个具体产品类,就必须增加一个相应的具体工厂类

代码:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass


class Alipay(Payment):
def __init__(self, use_huabei=False):
self.us_huabei = use_huabei

def pay(self, money):
if self.us_huabei:
print(f"花呗支付{money}元")
else:
print(f"支付宝支付{money}元")


class BankPay(Payment):
def pay(self, money):
print(f"银联支付{money}元")


class WechatPay(Payment):
def pay(self, money):
print(f"微信支付{money}元")


class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass


class AlipayFactory(PaymentFactory):
def create_payment(self):
return Alipay()


class WechatPayFactory(PaymentFactory):
def create_payment(self):
return WechatPay()


class HuabeiFactory(PaymentFactory):
def create_payment(self):
return Alipay(use_huabei=True)


class BankPayFactory(PaymentFactory):
def create_payment(self):
return BankPay()


if __name__ == '__main__':
pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)

抽象工厂模式

  • 内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
  • 例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
  • 相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。

建造者模式

  • 内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
  • 角色
    • 抽象建造者(Builder)
    • 具体建造者(Concrete Builder)
    • 指挥者(Director)
    • 产品(Product)
  • 建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象
  • 优点
    • 隐藏了一个产品的内部结构和装配过程
    • 将构造代码与表示代码分开
    • 可以对构造过程进行更精细的控制

单例模式

确保一个类只会创建出一个对象,并提供一个访问他的全局访问点

  • 角色
    • 单例(Singleton)
  • 优点
    • 对唯一实例的受控访问
    • 单例相当于全局变量,但防止了命名空间被污染—>不用单例也可以

一般日志系统会是单例,不然两个日志对象同时操作一个文件对象,会出现问题,

抽象工厂模式和建造者模式相对比简单工厂模式和工厂方法模式而言更灵活也更复杂

通常情况下、设计以简单工厂模式或工厂方法模式开始,当你发现设计需要更大的灵活性时,则像更复杂的设计模式演变

——-设计应当从简单开始,简单无法满足时才考虑复杂设计模式

结构型模式

适配器模式

  • 内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
  • 两种实现方式
    • 类适配器:使用多继承
    • 对象适配器:使用组合
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
30
31
32
33
34
35
36
37
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass

class Alipay(Payment):
def pay(self, money):
print(f"支付宝支付{money}元")


class WechatPay(Payment):
def pay(self, money):
print(f"微信支付{money}元")

class BankPay:
def cast(self, money):
print(f"银联支付{money}元")

# 类适配器
class NewBankPay(Payment, BankPay):
def pay(self, money):
self.cast(money)
p = NewBankPay()
p.pay(100)

# 对象适配器
class PaymentAdapter(Payment):
def __init__(self, payment):
self.payment = payment

def pay(self, money):
self.payment.cast(money)

p = PaymentAdapter(BankPay())
p.pay(100)

  • 角色:
    • 目标接口(Target)
    • 待适配的类(Adaptee)
    • 适配器(Adapter)
  • 适用场景
  • 想使用一个已经存在的类,而它的接口不符合你的要求
  • (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

桥模式

行为型模式


【python】之设计模式【未完】
http://example.com/2024/02/23/699python设计模式/
作者
Wangxiaowang
发布于
2024年2月23日
许可协议