zoukankan      html  css  js  c++  java
  • 创建型模式(一) 简单工厂模式、工厂模式与抽象工厂模式

    1、简单工厂模式

    简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式。它属于类创建型模式。
    • 创建型模式对类的实例化过程进行了抽象,能够将对象的创建与对象的使用过程分离。
    • 简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
    • 简单工厂模式包含三个角色:工厂角色负责实现创建所有实例的内部逻辑;抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口;具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
    • 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
    • 简单工厂模式最大优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类或工厂函数的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。
    • 简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心。
    #-*- coding:utf-8 -*-
    
    class CalcSuper:
        def __init__(self):
            self.result = 0
        def calc(self,num1, num2):
            return self.result
    
    
    class CalcAdd(CalcSuper):
        def calc(self,num1, num2):
            return num1+num2
    
    class CalcSub(CalcSuper):
        def calc(self,num1, num2):
            return num1-num2
    
    class CalcMul(CalcSuper):
        def calc(self,num1, num2):
            return num1*num2
    
    class CalcDiv(CalcSuper):
        def calc(self,num1, num2):
            return num1//num2
    
    
    def calc_factory(type):
        calc_dic = {
                '+':CalcAdd,
                '-':CalcSub,
                '*':CalcMul,
                '/':CalcDiv,
            }
        calc_obj = calc_dic[type]()
        return calc_obj
    
    
    calc1 = calc_factory('+')
    rst1 = calc1.calc(1,2)
    print(rst1)
    
    calc2 = calc_factory('*')
    rst2 = calc2.calc(2,3)
    print(rst2)

    结果:
    3
    6

    2、工厂模式

    工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。它属于类创建型模式。
    • 工厂方法模式又称为工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类
    • 工厂方法模式包含四个角色:抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,即产品对象的共同父类或接口;具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间往往一一对应;抽象工厂中声明了工厂方法,用于返回一个产品,它是工厂方法模式的核心,任何在模式中创建对象的工厂类都必须实现该接口;具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例。
    • 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
    • 工厂方法模式的主要优点是增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性;其缺点在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
    • 工厂方法模式适用情况包括:一个类不知道它所需要的对象的类;一个类通过其子类来指定创建哪个对象;将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。
    #-*- coding:utf-8 -*-
    
    class Payment:
        # 抽象产品
        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:
        # 抽象工厂
        def create_payment(self):
            pass
    
    
    class AliPayFactory(PaymentFactory):
        # 具体工厂
        def create_payment(self):
            return AliPay()
    
    
    class ApplePayFactory(PaymentFactory):
        def create_payment(self):
            return ApplePay()
    
    
    af = AliPayFactory()
    ali = af.create_payment()
    ali.pay(100)
    
    
    # 如果要新增支付方式
    class WechatPay(Payment):
        def pay(self, money):
            print('使用微信支付%s元' % money)
    
    
    class WechatPayFactory(PaymentFactory):
        def create_payment(self):
            return WechatPay()
    
    
    w = WechatPayFactory()
    wc = w.create_payment()
    wc.pay(200)

    结果:

    使用支付宝支付100元
    使用微信支付200元

    3、抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

    • 抽象工厂模式包含四个角色:抽象工厂用于声明生成抽象产品的方法;具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中;抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法;具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
    • 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。
    • 抽象工厂模式的主要优点是隔离了具体类的生成,使得客户并不需要知道什么被创建,而且每次可以通过具体工厂类创建一个产品族中的多个对象,增加或者替换产品族比较方便,增加新的具体工厂和产品族很方便;主要缺点在于增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
    • 抽象工厂模式适用情况包括:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节;系统中有多于一个的产品族,而每次只使用其中某一产品族;属于同一个产品族的产品将在一起使用;系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
    # -*- coding:utf-8 -*-
    
    # ------抽象产品------
    class PhoneShell:
        def show_shell(self):
            pass
    
    class CPU:
        def show_cpu(self):
            pass
    
    class OS:
        def show_os(self):
            pass
    
    # ------抽象工厂------
    class PhoneFactory:
        def make_shell(self):
            pass
    
        def make_cpu(self):
            pass
    
        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 Andriod(OS):
        def show_os(self):
            print('安卓系统')
    
    class IOS(OS):
        def show_os(self):
            print('iOS系统')
    
    # ------具体工厂------
    class HuaweiFactory(PhoneFactory):
        def make_shell(self):
            return SmallShell()
    
        def make_os(self):
            return Andriod()
    
        def make_cpu(self):
            return MediaTekCPU()
    
    class AppleFactory(PhoneFactory):
        def make_shell(self):
            return AppleShell()
    
        def make_os(self):
            return IOS()
    
        def make_cpu(self):
            return AppleCPU()
    
    # ------客户端------
    class Phone:
        def __init__(self,factory):
            self.factory = factory
            self.shell = self.factory.make_shell()
            self.os = self.factory.make_os()
            self.cpu = self.factory.make_cpu()
    
        def show_info(self):
            print('手机信息:')
            self.cpu.show_cpu()
            self.shell.show_shell()
            self.os.show_os()
    
    
    p1 = Phone(AppleFactory())
    p1.show_info()
    
    p2 = Phone(HuaweiFactory())
    p2.show_info()

    结果:

    手机信息:
    苹果CPU
    苹果机壳
    iOS系统


    手机信息:
    联发科CPU
    小手机壳
    安卓系统

  • 相关阅读:
    SQL: 返回刚插入记录的ID 及 output 更新记录时得到更新记录的ID值 .
    asp.net 用伪静态修改webconfig配置文件 .
    Asp.Net : 捕捉和记录网站中出现的所有未处理错误,抛出详细的页面来源和访问ip,调用的接口方法及异常实例(记事本日志,系统日志及数据库日志)
    js闭包(转载) (jquery ajax 异步 多循环运用 )
    c# enum 枚举名称和ID 互换获取.................
    WCF :服务开发与调用的完整示例
    关于DataSet 、 DataTable 、 ArrayList 、 IList 、Array
    Expression Tree不完全入门
    WF4 Beta2:IExecutionProperty的使用
    Groovy 1.8.9, 2.0.7 和 2.1.1 发布
  • 原文地址:https://www.cnblogs.com/dxnui119/p/11669401.html
Copyright © 2011-2022 走看看