1.简单工厂模式: 不直接向客户端暴露实现细节,创建一个工厂类负责创建实例。例如:

from abc import ABCMeta, abstractmethod


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


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

    def pay(self, money):
        if self.huabei == True:
            print("花呗支付:%d元", money)
        else:
            print("支付宝余额支付:%d元" % money)


class Wechatpay(Payment):
    def pay(self, money):
        print("微信支付:%d元" % money)


# 定义工厂
class PaymentFactory:
    def create_payment(self, method):
        if method == 'alipay':
            return Alipay()
        elif method == 'wechatpay':
            return Wechatpay()
        elif method == "huabei":  # 用户只要通过传递huabei字符串,就能调用花呗的功能,而不用去详细了解花呗的参数及实现
            return Alipay(huawei=True)
        else:
            return TypeError("Not such payment named:%s" % method)


if __name__ == '__main__':
    p = PaymentFactory()
    pay_way = p.create_payment('alipay')
    pay_way.pay(100)
    print('-------------')
    pay_way2 = p.create_payment('huabei')
    pay_way2.pay(200)

工厂模式

优点:封装了实现细节,调用者不需要知道如何实现,只要传递对应的信息,就能调用功能。

缺点:将好多功能写到了工厂类中,违反了单一职责原则。后期如果想添加功能,需要修改此类。

 

2.工厂方法模式:

改进简单工厂模式,将工厂类拆分为多个工厂。将工厂类改为抽象类。

# @Time : 8/5/21 10:26 AM 

# @Author : LY(Zhenghui.Lyu)

# @File : factory.py 

# @Software: PyCharm

# @Email: lzhfootmark@163.com

from abc import ABCMeta, abstractmethod


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


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

    def pay(self, money):
        if self.huabei == True:
            print("花呗支付:%d元" % money)
        else:
            print("支付宝余额支付:%d元" % money)


class Wechatpay(Payment):
    def pay(self, money):
        print("微信支付:%d元" % money)


# 定义工厂
# class PaymentFactory:
#     def create_payment(self, method):
#         if method == 'alipay':
#             return Alipay()
#         elif method == 'wechatpay':
#             return Wechatpay()
#         elif method == "huabei":  # 用户只要通过传递huabei字符串,就能调用花呗的功能,而不用去详细了解花呗的参数及实现
#             return Alipay(huawei=True)
#         else:
#             return TypeError("Not such payment named:%s" % method)


class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):  # 将此方法抽象
        pass


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


class WechatFactory(PaymentFactory):
    def create_payment(self):
        return Wechatpay()


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


if __name__ == '__main__':
    p = HuabeiFactory()
    pay_way = p.create_payment()
    pay_way.pay(1000)

可以看出工厂方法模式,添加新的支付方式,不影响之前的代码,但是代码量太大,创建一个方法就要添加一个新的工厂类。

 

3.抽象工厂模式

定义工厂类接口,让工厂类创建一系列相关对象。抽象工厂生产一套产品,而不是一个产品。

 

4.建造者模式

类似抽象工厂模式,能够更精细地控制创造各个部件的顺序。

 

5.单例模式

保证了一个类只有一个实例,有一个全局访问点。

class Singlemode:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):  # 如果此类没有实例
            cls._instance = super(Singlemode, cls).__new__(cls)  # 调用父方法创建实例
        return cls._instance


class Myclass(Singlemode):
    def __init__(self, a):
        self.a = a


if __name__ == '__main__':
    a = Myclass(20)
    b = Myclass(10)
    print(a.a)
    print(b.a)
    print(id(a), id(b))

例子中 a和b指向相同的对象。即只能创建一个对象。

 

6.适配器模式:

使原本接口不能兼容的,可以一起工作。

类适配器:使用继承

from abc import ABCMeta, abstractmethod


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


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

    def pay(self, money):
        if self.huabei == True:
            print("花呗支付:%d元" % money)
        else:
            print("支付宝余额支付:%d元" % money)


class Wechatpay(Payment):
    def pay(self, money):
        print("微信支付:%d元" % money)


class Bankpay:
    def cost(self, money):
        print('银联支付:%d元' % money)


class Newpay(Bankpay, Payment):  # 通过声明新适配器Newpay,使得原本cost和pay不兼容变得兼容
    def pay(self, money):
        self.cost(money)


# 此时想调用Bankpay,改为调用Newpay来使银联支付正常
p = Newpay()
p.pay(1000)  # 用pay(),调用cost()

 

对象适配器:使用组合,即类中有其他类的对象,通过此对象来实现调用另一个类中的功能。

from abc import ABCMeta, abstractmethod


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


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

    def pay(self, money):
        if self.huabei == True:
            print("花呗支付:%d元" % money)
        else:
            print("支付宝余额支付:%d元" % money)


class Wechatpay(Payment):
    def pay(self, money):
        print("微信支付:%d元" % money)


class Bankpay:
    def cost(self, money):
        print('银联支付:%d元' % money)


class Applepay:
    def cost(self, money):
        print('苹果支付:%d元' % money)


# class Newpay(Bankpay, Payment):  # 通过声明新适配器Newpay,使得原本cost和pay不兼容变得兼容
#     def pay(self, money):
#         self.cost(money)

class PaymentAdapter(Payment):  # 传入不同的实例,来引用不同的cost方法
    def __init__(self, payment):
        self.payment = payment

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

 

8.桥模式

解耦了功能代码,添加新类时,可以不更改之前的代码。

 

9.组合模式

 

10.外观模式:为一组接口提供一致的界面,使得子系统更加易用。

class CPU:
    def run(self):
        print("CPU运行")

    def stop(self):
        print("CPU停止")


class Disk:
    def run(self):
        print("disk运行")

    def stop(self):
        print("disk停止")


class Memory:
    def run(self):
        print("内存通电")

    def stop(self):
        print("内存断电")


class Computer:  # 通过Computer类封装
    def __init__(self):
        self.cpu = CPU()
        self.disk = Disk()
        self.memory = Memory()

    def run(self):
        self.cpu.run()
        self.disk.run()
        self.memory.run()

    def stop(self):
        self.cpu.stop()
        self.disk.stop()
        self.memory.stop()


computer1 = Computer()
computer1.run()
print('---')
computer1.stop()

 

11.代理模式

虚代理:如果没有必要创建某个对象时,可以用虚代理节省内存开销。

 

12.责任链模式

from abc import ABCMeta, abstractmethod


class Handler(metaclass=ABCMeta):
    @abstractmethod
    def handle_leave(self, day):  # 抽象方法,请假
        pass


class GeneralManager(Handler):
    def handle_leave(self, day):
        if day <= 10:
            print("总经理准假%d天" % day)
        else:
            print("你还是辞职吧")


class DepartmentManager(Handler):
    def __init__(self):
        self.next = GeneralManager()

    def handle_leave(self, day):
        if day <= 5:
            print('部门经理准假%d天' % day)
        else:
            print('部门经理权限不足')
            self.next.handle_leave(day)


class ProjectDirector(Handler):
    def __init__(self):
        self.next = DepartmentManager()

    def handle_leave(self, day):
        if day <= 1:
            print('项目经理准假%d天' % day)
        else:
            print('项目经理权限不足')
            self.next.handle_leave(day)


day = 5

h = ProjectDirector()  # 先传给首个主管,不管后面的如何判断
h.handle_leave(day)

耦合度降低了,一个对象不需知道是哪个对象处理其请求。

 

13.观察者模式,这是个比较重要的模式

from abc import ABCMeta, abstractmethod


class Observer(metaclass=ABCMeta):  # 观察者
    @abstractmethod
    def update(self, notice):  # 消息更新的抽象方法
        pass


class Notice:  # 发布者
    def __init__(self):
        self.observers = []  # 存储所有观察者

    def attach(self, obs):
        self.observers.append(obs)  # 添加订阅者

    def detach(self, obs):
        self.observers.remove(obs)  # 解除订阅者

    def notify(self):
        for i in self.observers:
            i.update(self)


class StaffNotice(Notice):  # 具体发布者
    def __init__(self, company_info=None):
        super().__init__()
        self.__company_info = company_info

    @property
    def company_info(self):
        return self.__company_info

    @company_info.setter
    def company_info(self, info):
        self.__company_info = info
        self.notify()  # 推送通知


# obj = StaffNotice(company_info='abc')
# obj.company_info = 'xyz'
# print(obj.company_info)


class Staff(Observer):  # 具体观察者
    def __init__(self):
        self.company_info = None

    def update(self, notice):
        self.company_info = notice.company_info


notice = StaffNotice('公司发布信息')
s1 = Staff()
s2 = Staff()
notice.attach(s1)
notice.attach(s2)

print(s1.company_info)
print(s2.company_info)
notice.company_info = '明天发奖金!'
print(s1.company_info)
print(s2.company_info)
notice.detach(s2)  # 解除s2观察者
notice.company_info = '后台公司倒闭'
print(s1.company_info)  # s1观察者更新信息
print(s2.company_info)  # s2观察者还是之前更新的状态