设计模式(工厂模式)

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 设计模式(工厂模式)

点击上方”python宝典”,关注获取python全套视频,

技术文章第一时间送达!

一、什么是设计模式

每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。” 每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。 GoF(Gang of Four) 设计模式四个基本要素:模式名称、问题、解决方案、效果

二、设计模式七大原则

1、开放封闭原则:一个软件实体如类,模块和函数应该对扩展是开放的,对修改是关闭的。即软件实体应尽量在不修改原有代码的情况下进行扩展(装饰器)

2、里氏替换原则:重写父类里面的方法,逻辑可能不一样,但是返回的结果参数啥的要一样(所有引用基类的地方必须能透明的使用其子类的对象)

3、依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象,要针对接口编程,而不是针对实现编程。(接口类)

4、接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要实现的接口

5、迪米特法则:一个软件实体应当尽可能少的与其他实体发生相互作用

6、单一职责原则:一个类只负责一项职责(不要存在多于一个导致类变更的原因,即一个类只负责一项职责)

7、合同复用原则:多用组合少用继承

       一个类重用另一个类的代码有两种方式

  •  继承
  •  组合
  • a、下面来说一下接口隔离原则

    接口隔离原则

    
    #假如说现在有这样的动物类
    from abc import abstractmethod,ABCMeta   #借助abc模块来实现接口
    #接口类就是为了提供标准,约束后面的子类
    
    # class Animal(metaclass=ABCMeta):
    #     @abstractmethod
    #     def walk(self):
    #         pass
    #
    #     @abstractmethod
    #     def fly(self):
    #         pass
    #
    #     @abstractmethod
    #     def swim(self):
    #         pass
    #
    # class Frog(Animal):
    #     '''像是这样定义一个青蛙类,由于接口类的方法都要被实现,而青蛙只会走,没不要要实现其他的方法
    #     动物不同会的功能也会不同,所以这时候我们就可以选择用接口隔离原则
    #     '''
    #     def walk(self):
    #         print('青蛙会走')
    #
    # obj = Frog()
    # obj.walk()   #会报错
    
    
    # =====================改进-=================
    class AnimalOnLand(metaclass=ABCMeta):
        '''在陆地上的动物'''
        @abstractmethod
        def walk(self):
            pass
    
    class AnimalInSky(metaclass=ABCMeta):
        '''飞行动物'''
        @abstractmethod
        def fly(self):
            pass
    
    class AnimalInWater(metaclass=ABCMeta):
        '''在水里的动物'''
        @abstractmethod
        def swim(self):
            pass
    
    class Tiger(AnimalOnLand):
        def walk(self):
            print('老虎在地上')
    
    class Frog(AnimalOnLand,AnimalInWater):
        def swim(self):
            print('青蛙会游')
    
        def walk(self):
            print('会跳')
    
    obj = Tiger()
    obj.walk()
    
    obj = Frog()
    obj.walk()
    obj.swim()
    

    b、继承和组合

    
    # 合同复用原则:多用组合少用继承
    class A:
        def test(self):
            return '你好啊'
    
    class B(A):  #继承
        def test(self):
            return 123
    
    class C:
        def __init__(self):
            self.a = A()   #组合
            self.a.test()
    
        def test(self): 
            return 789
    
    print(B().test())
    
    print(C().a)
    print(C().a.test())
    print(C().test())
    

    三、设计模式分类

    创建型模式:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式
  • 创建者模式
  • 原型模式
  • 单例模式
  • 总结创建型模式:

      依赖于继承的创建型模式:工厂方法模式

      依赖于组合的创建型模式:抽象工厂模式,创建者模式

    行为型模式:

  • 解释器模式
  • 责任链模式
  • 命令模式
  • 迭代器模式
  • 中介者模式
  • 备忘录模式
  • 观察者模式
  • 状态模式
  • 策略模式
  • 访问者模式
  • 模板方法模式
  • 结构性模式:

  • 适配器模式
  • 桥模式
  • 组合模式
  • 装饰模式
  • 外观模式
  • 享元模式
  • 代理模式
  • 四、简单工厂模式

    1、内容

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

    2、角色

  • 工厂角色(Creator)
  • 抽象产品角色(Product)
  • 具体产品角色(Concrete Product)
  • 3、优点

  • 隐藏了对象创建的实现细节
  • 客户端不需要修改代码
  • 4、缺点

  • 违反了单一职责原则,将创建逻辑集中到一个工厂类中
  • 当添加新产品时,需要修改工厂类代码,违反了开放封闭原则
  • 5、使用场景

  •  系统要独立于产品的创建与组合时
  •  强调一系列相关的产品对象的设计以便进行联合使用时 
  •  提供一个产品类库,想隐藏产品的具体实现时
  •  强调一系列相关的产品对象的设计以便进行联合使用时 

    6、代码示例

    原始的

    
    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self):
            pass
    
    class Alipay(Payment):
        def __init__(self,money):
            self.money = money
    
        def pay(self):
            print('支付宝支付了%s元'%self.money)
    
    class Whatpay(Payment):
        def __init__(self, money):
            self.money = money
    
        def pay(self):
            print('微信支付了%s元' % self.money)
    
    obj = Alipay(100)
    obj.pay()
    
    obj2 = Whatpay(200)
    obj2.pay()
    

    简单工厂

    
    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 Yuebao(Payment):
        def pay(self,money):
            print('余额宝支付了%s元' %money)
    
    class PaymentFactory:
        '''工厂类:封装了对象创建的细节'''
        def create_payment(self,method):
            if method =='alipay':
                return Alipay()
            elif method =='applepay':
                return Applepay()
            elif method =='yuebao':
                return Yuebao()
            else:
                return NameError(method)
    
    factory = PaymentFactory()
    alipay=factory.create_payment('yuebao')
    alipay.pay(100)
    

    五、工厂方法模式

    1、内容

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

    2、角色

  • 抽象工厂角色(Creator)
  • 具体工厂角色(Concrere Creator)
  • 抽象产品角色(Product)
  • 具体产品角色(Concrete Product)
  • 工厂方法模式相比简单工厂模式将每个具体产品都对应一个具体工厂

    3、优点

  • 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
  • 隐藏了对象创建的实现细节
  • 4、缺点

  • 每增加一个具体产品类,就必须增加一个相应的具体工厂类
  • 5、使用场景

  • 需要生产多种、大量复杂对象的时候
  • 需要降低耦合度的时候
  • 当系统的产品种类需要经常扩展的时候 
  • 6、代码示例

    
    from abc import ABCMeta,abstractmethod
    class PaymentFactory(metaclass=ABCMeta):
        @abstractmethod
        def create_payment(self):
            pass
    
    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 AlipayFactory(PaymentFactory):
        def create_payment(self):
            return Alipay()
    
    class AppleFactory(PaymentFactory):
        def create_payment(self):
            return Applepay()
    
    apple = AppleFactory()
    apple.create_payment().pay(100)
    
    alipay = AlipayFactory()
    alipay.create_payment().pay(300)
    
    #输出
    # 微信支付了100元
    # 支付宝支付了300

    六、抽象工厂模式

    1、内容

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

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

    2、角色

  • 抽象工厂角色(Creator)
  • 具体工厂角色(Concrete Creator)
  • 抽象产品角色(Product)
  • 具体产品角色(Concrete Product)
  • 客户端(Client)
  • 相比工厂方法模式,抽象工厂模式中的每个具体工厂都产生一套产品

    3、优点

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

  • 难以支持新种类的(抽象)产品
  • 5、使用场景

  • 系统要独立于产品的创建与组合时
  •  强调一系列相关的产品对象的设计以便进行联合使用时 
  •  提供一个产品类库,想隐藏产品的具体实现时
  • 6、代码示例

    
    from abc import abstractmethod,ABCMeta
    #==============抽象产品============
    class PhoneShell(metaclass=ABCMeta):
        '''手机壳'''
        @abstractmethod
        def show_shell(self):
            pass
    
    class CPU(metaclass=ABCMeta):
        '''CPU'''
        @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):
            '''制作cpu'''
            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 YingTeerCPU(CPU):
        def show_cpu(self):
            print('英特尔cpu')
    
    class MediaCPU(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_shell(self):
            return SmallShell()
    
        def make_cpu(self):
            return AppleCPU()
    
        def make_os(self):
            return Android()
    
    class HuaWeiactory(PhoneFactory):
        def make_shell(self):
            return BigShell()
    
        def make_cpu(self):
            return YingTeerCPU()
    
        def make_os(self):
            return Android()
    
    # ===============使用===============
    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(HuaWeiactory())
    p1.show_info()
    
    p2 = make_phone(MiFactory())
    p2.show_info()
    
    设计模式(工厂模式)

    识别图中二维码,欢迎关注python宝典

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 设计模式(工厂模式)


     上一篇
    树和二叉树简介 树和二叉树简介
    点击上方”python宝典”,关注获取python全套视频, 技术文章第一时间送达! 一、树1、什么是树? 树状图是一种数据结构,它是由n(n=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,
    2021-04-05
    下一篇 
    设计模式(建造者模式) 设计模式(建造者模式)
    点击上方”python宝典”,关注获取python全套视频, 技术文章第一时间送达! 建造者模式1、内容 将一个复杂对象的构建与它表示分离,使得同样的构建过程可以创建不同的表示 2、角色 抽象建造者 具体建造者 指挥者 产品
    2021-04-05