zoukankan      html  css  js  c++  java
  • 设计模式:工厂方法模式

    一、简单工厂模式

    1、内容

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

    关注的是对象创建的细节

    2、角色

    1、工厂角色(Factory)

    class PaymentFactory: #工厂类 封装了对象创建的细节
        def create_payment(self, method):
            if method == "alipay":
                return Alipay()
            elif method == "yuebao":
                return Alipay(True)
            elif method == "applepay":
                return ApplePay()
            else:
                raise NameError(method)
    
    f = PaymentFactory()
    p = f.create_payment("alipay")
    p.pay(100)

    2、抽象产品角色(Product)

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

    3、具体产品角色(Concrete Product)

    class Alipay(Payment):
        def __init__(self, enable_yuebao=False):
            self.enable_yuebao = enable_yuebao
    
        def pay(self, money):
            if self.enable_yuebao:
                print("余额宝支付%s元" % money)
            else:
                print("支付宝支付%s元" % money)
    
    class ApplePay(Payment):
        def pay(self, money):
            print("苹果支付%s元" % money)

    4、完整的代码

    from abc import abstractmethod, ABCMeta
    
    
    #抽象产品角色
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self, money):
            pass
    
    #具体产品角色
    class Alipay(Payment):
        def __init__(self, enable_yuebao=False):
            self.enable_yuebao = enable_yuebao
    
        def pay(self, money):
            if self.enable_yuebao:
                print("余额宝支付%s元" % money)
            else:
                print("支付宝支付%s元" % money)
    
    class ApplePay(Payment):
        def pay(self, money):
            print("苹果支付%s元" % money)
    
    #工厂角色
    class PaymentFactory: #工厂类 封装了对象创建的细节
        def create_payment(self, method):
            if method == "alipay":
                return Alipay()
            elif method == "yuebao":
                return Alipay(True)
            elif method == "applepay":
                return ApplePay()
            else:
                raise NameError(method)
    
    f = PaymentFactory()
    p = f.create_payment("alipay")
    p.pay(100)

    3、uml

    4、优点

    1、隐藏了对象创建的实现细节,客户端不需要修改代码

    1、实现代码

    class PaymentFactory: #工厂类 封装了对象创建的细节
        def create_payment(self, method):
            if method == "alipay":
                return Alipay()
            elif method == "yuebao":
                return Alipay(True)
            elif method == "applepay":
                return ApplePay()
            else:
                raise NameError(method)
    f = PaymentFactory()
    p = f.create_payment("alipay")
    p.pay(100)
    

    2、输出

    "C:Program FilesPython35python.exe" F:/1_factory.py
    支付宝支付100元
    
    Process finished with exit code 0

    5、缺点

    违反了单一职责原则,将创建逻辑集中到一个工厂类里,当添加新产品时,需要修改工厂类代码,违反了开闭原则

    6、案例

    1、现在要加一个支付宝

    class Alipay(Payment):
        def __init__(self, enable_yuebao=False):
            self.enable_yuebao = enable_yuebao
    
        def pay(self, money):
            if self.enable_yuebao:
                print("余额宝支付%s元" % money)
            else:
                print("支付宝支付%s元" % money)
    

    2、对用户隐藏细节

    class PaymentFactory:
        def create_payment(self, method):
            if method == "alipay":
                return Alipay()
            elif method == "yuebao":
                return Alipay(True)
            elif method == "applepay":
                return ApplePay()
            else:
                raise NameError(method)
    
    f = PaymentFactory()
    p = f.create_payment("yuebao")
    p.pay(100)
    
    			
    "C:Program FilesPython35python.exe" F:/1_factory.py
    余额宝支付100元
    
    Process finished with exit code 0

    二、工厂方法模式

    1、内容

    定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。

    2、角色

    1、抽象工厂角色(Creator)

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

    2、具体工厂角色(Concrete Creator)

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

    3、抽象产品角色(Product)

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

    4、具体产品角色(Concrete Product)

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

    5、完成代码

    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 PaymentFactory(metaclass=ABCMeta):
        @abstractmethod
        def create_payment(self):
            pass
    
    #具体工程角色
    class AlipayFactory(PaymentFactory):
        def create_payment(self):
            return Alipay()
    
    class ApplePayFactory(PaymentFactory):
        def create_payment(self):
            return ApplePay()
    
    
    # 用户输入
    # 支付宝,120
    
    af = AlipayFactory()
    ali = af.create_payment()
    ali.pay(120)

    3、优点

    1、每个具体产品都对应一个具体工厂类,不需要修改工厂类代码

    2、工厂类可以不知道它所创建的对象的类

    3、隐藏了对象创建的实现细节

    4、缺点

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

    5、适用场景

    1、需要生产多种、大量复杂对象的时候

    2、需要降低耦合度的时候

    3、当系统中的产品种类需要经常扩展的时候

    6、uml类图

    1、说明

    1、三角:继承
    2、虚线:是依赖
    3、虚线圆圈:是注释

    7、案例

    1、如何创建

    af = AlipayFactory()
    ali = af.create_payment()
    ali.pay(120)
    
    
    "C:Program FilesPython35python.exe" F:/2_factory_method.py
    支付宝支付120元
    
    Process finished with exit code 0 

    三、抽象工厂模式

    1、内容

    定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象

    生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。

    2、角色

    1、完整代码

    from abc import abstractmethod, ABCMeta
    
    # ------抽象产品------
    class PhoneShell(metaclass=ABCMeta):
        @abstractmethod
        def show_shell(self):
            pass
    
    class CPU(metaclass=ABCMeta):
        @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):
            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 SnapDragonCPU(CPU):
        def show_cpu(self):
            print("骁龙CPU")
    
    
    class MediaTekCPU(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_cpu(self):
            return SnapDragonCPU()
    
        def make_os(self):
            return Android()
    
        def make_shell(self):
            return BigShell()
    
    
    class HuaweiFactory(PhoneFactory):
        def make_cpu(self):
            return MediaTekCPU()
    
        def make_os(self):
            return Android()
    
        def make_shell(self):
            return SmallShell()
    
    
    class IPhoneFactory(PhoneFactory):
        def make_cpu(self):
            return AppleCPU()
    
        def make_os(self):
            return IOS()
    
        def make_shell(self):
            return AppleShell()
    
    
    # ------客户端------
    
    
    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(IPhoneFactory())
    p1.show_info()
    

    2、角色介绍 

    1. 抽象工厂角色(Creator)
    2. 具体工厂角色(Concrete Creator)
    3. 抽象产品角色(Product)
    4. 具体产品角色(Concrete Product)
    5. 客户端(Client)

    相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。

    3、UML类图

    4、缺点

    难以支持新种类的(抽象)产品

    3、优点

    1. 将客户端与类的具体实现相分离
    2. 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
    3. 有利于产品的一致性(即产品之间的约束关系)

    4、应用场景

    1. 系统要独立于产品的创建与组合时
    2. 强调一系列相关的产品对象的设计以便进行联合使用时
    3. 提供一个产品类库,想隐藏产品的具体实现时
  • 相关阅读:
    Docker容器(一):什么是Docker
    使用docker简单启动springboot项目
    nginx的alias与root的区别
    拦截器报循环依赖错误
    给jenkins更换工作空间
    The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    No Compiler is Provided in this environment Perhaps you are running on JRE rather than a JDK
    idea拉取最新代码弹窗(Ctrl + T)
    idea常用插件
    SqlDependency数据库缓存
  • 原文地址:https://www.cnblogs.com/luoahong/p/9734352.html
Copyright © 2011-2022 走看看