23种设计模式-python实现

文章目录

  • 五大原则
  • 设计模式的类别
  • python 实现
    • 行为型
    • 结构型
    • 创建型

五大原则

  1. 单一职责原则(Single responsibility principle)
    每个类只完成一项功能,仅有一个引起它变化的原因。
    优点:
    降低类的复杂度和变更引起的风险;
    提高类的可读性,可维护性。

  2. 接口隔离原则(Interface Segregation Principle)
    接口中的方法尽量少,内部的操作尽量不暴露给其他接口。
    实现低耦合高内聚。

  3. 里氏替换原则(Liskov Substitution Principle)
    父类适用的地方,子类必定也可以使用。

  4. 开闭原则(Open Closed Principle)
    一个软件实体(如模块、类、函数)对修改代码关闭扩展功能开放,提高代码的复用性、可维护性。

  5. 依赖倒置原则(Dependence Inversion Principle)
    高层模块不应该依赖于低层模块,二者都应该依赖于抽象;
    解耦
    继承是增加耦合性,尽量使用组合的方式解耦。

设计模式的类别

  1. 行为型
    策略模式,
  2. 结构型
    装饰器模式,适配器模式,
  3. 创建型(5)
    单例模式,工厂模式(简单工厂、工厂方法),抽象工厂,原型模式,建造者模式

python 实现

行为型

  1. 策略模式
    类可以根据不同的场景,选择不同的策略算法。
"""
    策略模式  行为型
    类可以根据不同的场景,选择不同的策略算法。

    数据结构:字典
    {
        场景名字: 策略函数,
    }

    注册策略,添加key-value
    获取策略
"""


# 策略管理类
class StrategyManager:
    """ 策略管理类 """
    def __init__(self):
        self.strategy = {}

    def get_strategy(self, scene):
        """ 获取策略函数 """
        return self.strategy.get(scene)

    def register_strategy(self, scene, func):
        """ 注册场景策略 """
        self.strategy[scene] = func


# 策略类
class Strategy:
    """ 策略类, 算法函数实现 """
    @staticmethod
    def drive_car():
        print("驾驶小汽车...")

    @staticmethod
    def drive_moto():
        print("骑摩托车...")

    @staticmethod
    def drive_bike():
        print("骑自行车...")


# 场景类
class Scene:
    """ 场景类 """
    def __init__(self, name):
        self.name = name


if __name__ == '__main__':
    strategy_manager = StrategyManager()
    # 注册策略
    strategy_manager.register_strategy("city", Strategy.drive_car)
    strategy_manager.register_strategy("country", Strategy.drive_moto)
    strategy_manager.register_strategy("mountain", Strategy.drive_bike)

    # 选择山区策略
    strategy_manager.get_strategy("mountain")()

结构型

  1. 装饰器模式
    使用类装饰一个对象,不改变其代码的情况下,扩展其功能。
"""
    装饰器模式, 结构型
    使用类装饰一个对象,不改变其代码的情况下,扩展其功能

    普通类(被装饰)

    装饰类

    包裹类
"""


# 普通类
class Person:
    def __init__(self, name):
        self.name = name

    def intro(self):
        print(f"{self.name} 是普通人...")


# 装饰类
class SaiWen:
    def __init__(self, person):
        self.person = person

    def da_gai_shou(self):
        print(f"{self.person.name} 是奥特曼, 正在打怪兽...")


# 包裹类
class Wrapper:
    def __init__(self, person, deco_class):
        self.person = person
        self.deco = deco_class(person)

    def __getattr__(self, attr):
        try:
            return getattr(self.person, attr)
        except AttributeError:
            return getattr(self.deco, attr)


if __name__ == '__main__':
    person = Person("jack")
    person.intro()

    # 装饰person对象
    wrapper = Wrapper(person, SaiWen)
    wrapper.intro()
    wrapper.da_gai_shou()

  1. 适配器模式
    将不同的接口,统一适配到同一个接口。
    23种设计模式-python实现_第1张图片
# 被适配的类
class AliPay:
    def ali_pay(self, sum):
        print("ali pay $%s" % sum)


class WeichatPay:
    def weichat_pay(self, sum):
        print("weichat pay $%s" % sum)


# 适配器类
class Adapter:
    def __init__(self, pay_mode, pay_api) -> None:
        self.pay_mode = pay_mode()
        self.pay_api = pay_api
        self.check_pay()

    def check_pay(self):
        if not hasattr(self.pay_mode, self.pay_api):
            raise AttributeError(
                "Unsupported payment method:%s" % self.payMethod)

    def pay(self, sum):
        method = getattr(self.pay_mode, self.pay_api)
        return method(sum)


if __name__ == "__main__":
    # 对支付方案套上适配器
    ali_pay = Adapter(AliPay, "ali_pay")
    weichat_pay = Adapter(WeichatPay, "weichat_pay")

    # 适配到同一个pay的接口
    ali_pay.pay(100)
    weichat_pay.pay(100)

创建型

  1. 单例模式
    类,只创建一个对象
class Singleton(object):
    def __new__(cls, *args, **kwargs):
    	# 只创建一个对象
        if hasattr(cls, "_Singleton__instance"):
            return cls.__instance

        cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, *args, **kwargs):
    	# 只初始化一次
        if hasattr(self, "_Singleton__init"):
            return
        object.__init__(self)
        self.__init = True

    def __eq__(self, other):
        if self is other:
            print("是同一个对象")
        else:
            print("不是同一个对象")


if __name__ == '__main__':
    s = Singleton()
    s2 = Singleton()

    print(s == s2)

  1. 工厂模式

简单工厂模式
工厂方法模式
抽象工厂模式

简单工厂

"""
    简单工厂模式
    将不同的产品类,传入同一个工厂类的函数中;隐藏创建对象的细节,但违反了单一职责的原则


    工厂方法模式
    将不同的产品类,传入各自的工厂类的函数中,来生成对象。 保持单一职责原则
	(也可以使用一个工厂类的静态方法)
"""


# 手机基类
class BasePhone:
    def __init__(self, model, color):
        self.model = model
        self.color = color

    def get_info(self):
        return "产品信息".center(20, "=") + "\n" \
        + "手机品牌:%s"%self.brand + "\n" \
        + "手机颜色:%s"%self.color


# 华为手机
class HuaweiPhone(BasePhone):
    def __init__(self, model, color):
        super(HuaweiPhone, self).__init__(model, color)
        self.brand = __class__.__name__


# OPPO
class OPPOPhone(BasePhone):
    def __init__(self, model, color):
        super(OPPOPhone, self).__init__(model, color)

        # self可以省略
        self.brand = self.__class__.__name__


# (一个)工厂类--> 简单工厂模式
class Factory:
    def produce(self, phone_class, *args):
        """
            phone_class: 产品类;
            model: 产品模式;
            color: 产品颜色
        """
        phone = phone_class(*args)
        return phone


if __name__ == '__main__':
    factory = Factory()
    huawei_phone = factory.produce(HuaweiPhone, "4G", "天蓝色")
    print(huawei_phone.get_info())

抽象的工厂模式

"""
    抽象的工厂
"""


# 生产奔驰轮胎的厂商
class BenzTiresFactory:
    def get_info(self):
        return "tires made by Benz"


# 生产奔驰底盘的厂商
class BenzChassisFactory:
    def get_info(self):
        return "chassis made by Benz"


# 生产奔驰其他零部件的厂商
class BenzOtherFactory:
    def get_info(self):
        return "other made by Benz"


# 奔驰车类
class BenzCar:
    def __init__(self, color):
        self.brand = self.__class__.__name__[:-3]
        self.color = color
        self.tires = None
        self.chassis = None
        self.other = None

    def get_info(self):
        return "车辆信息".center(20, "=") + "\n" \
        + "品牌:%s"%self.brand + "\n" \
        + "颜色:%s"%self.color


# 工厂类
class BenzFactory:
    def __init__(self, color):
        self.car = BenzCar(color)

    def build_car(self, tires_factory, chassis_factory, other_factory):
        # 由厂家内部根据指定零件厂商,开始制造零件
        self.make_tires(tires_factory)
        self.make_chassis(chassis_factory)
        self.make_other(other_factory)

    def get_car(self):
        return self.car

    def make_tires(self, tires_factory):
        tires = tires_factory()
        self.car.tires = tires

    def make_chassis(self, chassis_factory):
        chassis = chassis_factory()
        self.car.chassis = chassis

    def make_other(self, other_factory):
        other = other_factory()
        self.car.other = other


# 品牌专卖店
class BenzStore:
    def buy_car(self, color):
        # 颜色
        self.factory = BenzFactory(color)

        # 轮胎、底盘、其他零件均为奔驰制造
        self.factory.build_car(BenzTiresFactory, BenzChassisFactory, BenzOtherFactory)
        #
        return self.factory.get_car()


if __name__ == "__main__":
    # 实例化奔驰专卖店
    benz_store = BenzStore()
    # 去专卖店买车
    benz_car = benz_store.buy_car("black")
    print(benz_car.get_info())

  1. 原型模式
    创建一个对象模板,复制出多个重复的对象,并修改其属性值。
    简化对象的创建(不受构造函数的影响),提高性能,节约内容。

注意:复制对象会执行__new__,不会执行__init__。
23种设计模式-python实现_第2张图片

from copy import copy, deepcopy


# 手机原型
class PhonePrototype:
    def __init__(self) -> None:
        self.cpu = None
        self.color = None

    def get_info(self):
        return "cpu: %s\ncolor: %s" % (self.cpu, self.color)


# 原型建造类
class Prototype:
    def __init__(self) -> None:
        self.prototype = PhonePrototype()

    def get_phone(self, cpu, color):
        phone = deepcopy(self.prototype)
        phone.__dict__.update({"cpu": cpu, "color": color})
        return phone


if __name__ == "__main__":
    pro = Prototype()
    phone1 = pro.get_phone(cpu="Intel", color="black")
    phone2 = pro.get_phone(cpu="AMD", color="blue")
    print("手机1:\n", phone1.get_info())
    print("手机2:\n", phone2.get_info())

  1. 建造者模式
    使用简单的对象,一步一步地构建出复杂的对象。
    可以对过程进行精细化控制;产品必须有共同点,范围有限制。
# 产品类
class Product:
    def __init__(self) -> None:
        self.hamburger = None
        self.coke = None

    def __str__(self) -> str:
        return "Product".center(20, "=") + \
            "\n" + ("hamburger : %s" % self.hamburger).center(20, " ") + \
            "\n" + ("coke : %s" % self.coke).center(20, " ") + \
            "\n" + "=" * 20

# 套餐1
class BeefPackage:
    def __init__(self) -> None:
        self.product = Product()

    def build_hamburger(self):
        self.product.hamburger = "Beaf Hamburger"

    def build_coke(self):
        self.product.coke = "Coca Cola"

# 套餐2
class ChickenPackage:
    def __init__(self) -> None:
        self.product = Product()

    def build_hamburger(self):
        self.product.hamburger = "Chicken Hamburger"

    def build_coke(self):
        self.product.coke = "Pepsi Cola"

# 建造者类
class Store:
    def get_product(self):
        package = None
        choice = input(
            "Please Choice Your Package\na.Beef Package\nb.Chicken Package\n>>> ").strip()
        if choice == "a":
            package = BeefPackage()
        elif choice == "b":
            package = ChickenPackage()
        else:
            raise ValueError("don't have package choice %r" % choice)

        # 建造食品
        package.build_hamburger()
        package.build_coke()
        return package.product


if __name__ == "__main__":
    s = Store()
    product = s.get_product()
    print(product)

你可能感兴趣的:(python基础,设计模式,python)