建立型模式

  建立型模式:工厂方法模式、抽象工厂模式、建立者模式、原型模式、单例模式。
python

1、简单工厂模式

  不直接向客户端暴露对象建立的实现细节,而是经过一个工厂类来负责建立产品类的实例。该模式不属于23种设计模式之一。shell

一、简单工程模式示例

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
    # abstract class
    @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:
            print('支付宝支付%d元' % money)
        else:
            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()
        elif method == 'wechat':
            return WechatPay()
        elif method == 'huabei':
            return Alipay(use_huabei=True)
        else:
            raise TypeError("No such payment named %s" % method)


pf = PaymentFactory()
# p = pf.create_payment('alipay')
p = pf.create_payment('huabei')   # 隐藏了类的内部实现,无需了解代码逻辑
p.pay(100)

 

  Payment是抽象类,是为了让产品有一样的表现,能够一样的对外使用。若是要增长新的支付,好比银行支付,只要添加新的产品类便可。数据库

二、简单工厂模式总结

角色:设计模式

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

优势:微信

  • 隐藏了对象建立的实现细节
  • 客户端不须要修改代码

缺点:函数

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

2、工厂方法模式

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

一、工厂方法模式示例

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):   # 产品接口
    # abstract class
    @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:
            print('支付宝支付%d元' % money)
        else:
            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=ABCMeta):   # 工厂类接口
    @abstractmethod
    def create_payment(self):
        pass

class AlipayFactory(PaymentFactory):   # 具体工厂类
    def create_payment(self):
        return Alipay()

class WechatPayFactory(PaymentFactory):
    def create_payment(self):
        return WechatPay()

class HuabeiFactory(PaymentFactory):
    def create_payment(self):
        return Alipay(use_huabei=True)

class BankPayFactory(PaymentFactory):   # 建立新产品对应的工厂
    def create_payment(self):
        return BankPay()

pf = HuabeiFactory()  # 建立工厂
p = pf.create_payment()
p.pay(100)

二、工厂方法模式总结

角色:ui

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

优势:spa

  • 每一个具体产品都对应一个具体工厂类,不须要修改工厂类代码
  • 隐藏了对象建立的实现细节

缺点:操作系统

  • 每增长一个具体产品类,就必须增长一个响应的具体工厂类(代码太多了)

3、抽象工厂模式

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

一、抽象工厂模式示例

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

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):
        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()    # 苹果cpu

    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()

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

二、抽象工厂模式总结

角色:

  • 抽象工厂角色(Creator)
  • 具体工厂角色(Concrete Creator)
  • 抽象产品角色(Product)
  • 具体产品角色(Concrete Product)
  • 客户端(Client)

优势:

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

缺点:

  • 难以支持新种类的(抽象)产品:好比在CPU、手机壳、系统外再加一个内存,就很是难添加,该模式不多会用到。

4、建立者(建造者)模式

  将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。

一、建造者模式示例

from abc import ABCMeta, abstractmethod

class Player:  # 产品:游戏角色
    def __init__(self, face=None, body=None, arm=None, leg=None):   # 传入初始化参数
        self.face = face
        self.body = body
        self.arm = arm
        self.leg = leg

    def __str__(self):
        return "%s, %s, %s, %s" % (self.face, self.body, self.arm, self.leg)


class PlayerBuilder(metaclass=ABCMeta):  # 抽象建造者:抽象类做为接口
    @abstractmethod
    def build_face(self):
        pass

    @abstractmethod
    def build_body(self):
        pass

    @abstractmethod
    def build_arm(self):
        pass

    @abstractmethod
    def build_leg(self):
        pass


class SexyGirlBuilder(PlayerBuilder):  # 具体建立者:女性角色
    def __init__(self):
        self.player = Player()   # 玩家

    def build_face(self):
        self.player.face = "漂亮脸蛋"

    def build_body(self):
        self.player.body = "苗条"

    def build_arm(self):
        self.player.arm = "漂亮胳膊"

    def build_leg(self):
        self.player.leg = "大长腿"


class Monster(PlayerBuilder):   # 具体建立者:怪物
    def __init__(self):
        self.player = Player()

    def build_face(self):
        self.player.face = "怪兽脸"   # 被隐藏的产品内部结构,也是表示代码

    def build_body(self):
        self.player.body = "怪兽身材"  # 被隐藏的产品内部结构,也是表示代码

    def build_arm(self):
        self.player.arm = "长毛的胳膊"

    def build_leg(self):
        self.player.leg = "长毛的腿"


class PlayerDirector:    # 指挥者:控制组装顺序
    def build_player(self, builder):
        builder.build_body()  # 被隐藏的装配过程,也是构造代码
        builder.build_face()  # 被隐藏的装配过程,也是构造代码
        builder.build_arm()
        builder.build_leg()
        return builder.player


# client调用
# builder = SexyGirlBuilder()   # 建立一个性感女孩builder
builder = Monster()    # 建立一个怪物builder
director = PlayerDirector()  # 指挥者实例化
p = director.build_player(builder)   # 组装建立(不一样角色建立函数都是相同的)
print(p)

  

二、建造者模式总结

角色:

  • 抽象建造者(Builder)
  • 具体建造者(Concrete Builder)
  • 指挥者(Director)
  • 产品(Product)

优势:

  • 隐藏了一个产品的内部结构和装配过程
  • 将构造代码与表示代码分开
  • 能够对构造过程进行更精细的控制

建造者模式与抽象工厂模式对比:

  建造者模式与抽象工厂模式类似,也用来建立复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象(控制它的顺序),而抽象工厂模式着重于多个系列的产品对象。

5、单例模式

  保证一个类只有一个实例,并提供一个访问它的全局访问点。

一、单例模式示例

from abc import abstractmethod, ABCMeta

# 经过 __new__ 方法是实现单例模式的的一种方式,若是实例对象存在了就直接返回该实例便可,若是尚未,那么就先建立一个实例,再返回。
class Singleton:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):  # 反射查看是否有_instance的类属性
            cls._instance = super(Singleton, cls).__new__(cls)   # 调用父类的__new__方法来建立实例
        return cls._instance

class MyClass(Singleton):
    def __init__(self, a):
        self.a = a


a = MyClass(10)
b = MyClass(20)

print(a.a)  # 输出20
print(b.a)  # 输出20

print(id(a), id(b))   # 4400380840 4400380840, id相同说明二者是同一个实例

# 常应用于日志文件对象,数据库链接器对象,操做系统文件对象等状况使用。

  

二、单例模式总结

角色:

  • 单例(Singleton):全部它的子类都知足单例模式

优势:

  • 对惟一示例的受控访问
  • 单例至关于全局变量,但防止了命名空间被污染(一个名字是全局变量时,在整个命名空间里这个名字就被占用了,再使用这个名字会冲突)

6、建立型模式小结

  抽象工厂模式和建造者模式相比于简单工厂模式和工厂方法模式而言更灵活也更复杂。

  一般状况下、设计以简单工厂模式或工厂方法模式开发,当你发现设计须要更大的灵活性时,则向更复杂的设计模式演化。

相关文章
相关标签/搜索