欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式02、单例模式 简单工厂 工厂方法 抽象工厂方法

程序员文章站 2024-01-20 15:41:10
...

01、单例模式

--单例模式:通过python语法控制使得一个类只能实例化一个实例
--代码示例:
class Single():
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_single"):
            cls._single = super(Single, cls).__new__(cls)
        return cls._single

class Method(Single):
    def __init__(self, a):
        self.a = a


b = Method(16)
c = Method(89)

print(b.a, c.a) // b.a = c.a表示他们是同一个实例
print(id(b), id(c)) // 而保存地址相同则进一步证明了上述观点
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
89 89
1414286276592 1414286276592

--单例基本应用介绍:
	--保证一个类只有一个全局访问点,只有一个实例
	--单例相当于全局变量,防止命名空间被污染
	--相较于全局变量,单例模式下全局变量可以出现多个名称
	
注:设计模式越简单越好,当为了设计更加灵活的系统时可以考虑采取更复杂的模式来满足设计需求

02、new() init() super() self cls这几个属性的讲解

--super()

--__new__()

--__init__()

--self

--cls

03、抽象基类

--抽象基类:
	--抽象基类只能被继承,不能被实例化[强制要求],也并不实现其中的方法[约定俗成]
	--继承抽象基类的子类必须实现抽象基类中的抽象方法
	
--抽象方法申明:abc.abstractmethod
import abc

class Person(abc.ABC):
    @abc.abstractmethod
    def run(self):
        pass

class Man(Person):
    def run(self):
        print("已经跑了1000km")
    def eat(self):
        print("今天吃了一碗饭")

jack = Man()
jack.eat()
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
如果Man没有实现run方法会报错如下:
	TypeError: Can't instantiate abstract class Man with abstract methods run

04、简单工厂模式

--工厂类:不直接向客户端暴露创建对象的实现细节,而是通过一个工厂类来负责创建产品类的实例
	--工厂角色[Productor]:
	--抽象产品角色[Abstract_Production]:
	--具体产品角色[Concrete_Production]:
--优点:
	--隐藏了对象创建的实现细节
	--客户端不需要修改代码
--缺点:
	--违反了单一职责原则,将多种创建逻辑实现到了一个工厂类中
	--当添加新产品时,需要修改工厂类代码违反了开闭原则
注:因此简单工厂模式不是23中设计模式之一
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
import abc

# 支付基类
class Payment(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def pay(self, money):
        pass

# 两个支付类型: 也可以视为两个支付的接口
class Alipay(Payment):
    def __init__(self, use_huabei=False):
        self.use_huabei = use_huabei

    def pay(self, money):
        if self.use_huabei == True:
            print("花呗支付%d元." % money)
        elif self.use_huabei == False:
            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()
        if method == "wechat":
            return WeChatpay()
        elif method == "huabei":
            return Alipay(use_huabei=True)
        else:
            raise TypeError("没有 %s 这样的支付方式" % method)

pf = PaymentFactory()
ali_py = pf.create_payment("alipay")
ali_py.pay(39)

ali_hb_py = pf.create_payment("huabei")
ali_hb_py.pay(18)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
支付宝余额支付39元.
花呗支付18元.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
--这种方式:
	--工厂类返回实例将不同行为类的参数差异统一为一套参数体系,在使用时针对不同行为使用不同参数即可,无需调用者考虑
	--工厂类返回一个实例可以帮助隐藏一些参数,不需要使用者去考虑能够大大减轻使用的负担,尤其是一些科学方法/算法不需要使用者清楚每个参数的含义即可使用
	--工厂类在返回实例时,可以根据不同行为类做一些处理,减少使用接口的难度

05、工厂方法模式

--简单工厂的坏处是:一个工厂类封装了多个产品的逻辑,这是违反设计原则的;解决方式就是:每一个产品都给一个工厂就好了

--工厂模式:定义一个用于创建对象的工厂接口,让子类决定实例化哪个产品类
--角色:
	--抽象工厂角色
	--具体工厂角色
	--抽象产品角色
	--具体产品角色
--优点:
	--每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
	--隐藏了对象创建的实现细节
--缺点:
	--每增加一个具体的产品类,就必须增加一个具体的工厂类
	
--代码实现:
import abc

# 支付基类
class Payment(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def pay(self, money):
        pass

# 两个支付类型: 也可以视为两个支付的接口
class Alipay(Payment):
    def __init__(self, use_huabei=False):
        self.use_huabei = use_huabei

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

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

# 新增支付方式:
class Bankpay(Payment):
    def pay(self, money):
        print("银联支付%d元." % money)

# 创建工厂类:根据输入生产一个支付
class PaymentFactory(metaclass=abc.ABCMeta):
    @abc.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(use_huabei=True)

# 新增银联支付工厂
class BankFactory(PaymentFactory):
    def create_payment(self):
        return Bankpay()

# 花呗支付
pf = HuaBeiFactory()
pf_hb = pf.create_payment()
pf_hb.pay(100)

# 新增银联支付
yl = BankFactory()
yl_zf = yl.create_payment()
yl_zf.pay(102)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
花呗支付100元.
银联支付102元.

06、抽象工厂模式

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

--代码:

07、设计模式与面向对象介绍


08、面向对象设计原则