设计模式

接口:一种特殊的类,声明了若干抽象方法,要求继承该接口的类必须实现这些方法

from abc import ABCMeta,abstractmethod

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

class WechatPay(Payment):
    pass

p = WechatPay()

  

单例模式

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'_instance'):
            cls._instance = object.__new__(cls)
        return cls._instance

class Logger(Singleton):
    def __init__(self,info):
        self.info = info

a = Logger('a')
print(a)
print(a.info)

b = Logger('b')
print(b)
print(b.info)

  

简单工厂

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

角色

  • 工厂角色
  • 抽象产品角色
  • 具体产品角色
from abc import ABCMeta,abstractmethod

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

class AliPay(PayMent):
    def pay(self,money):
        print("支付宝支付%s"%money)

class WechatPay(PayMent):
    def pay(self,money):
        print("微信支付%s"%money)

class PayFactory(object):
    def create_payment(self,method):
        if method == "alipay":
            return AliPay()
        elif method == "wechatpay":
            return WechatPay()

f = PayFactory()
p = f.create_payment("alipay")
p.pay(100)

  

工厂方法模式

应用场景:系统中的产品种类需要经常扩展的时候

优点:

  • 每个具体产品对应一个具体工厂类,不需要修改工厂类代码
  • 工厂类可以不知道它所创建的对象的类
  • 隐藏了对象创建的实现细节

缺点:

  • 每新增一个具体产品类,就必须增加一个相应的具体工厂类
from abc import ABCMeta,abstractmethod

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

class AliPay(Payment):
    def pay(self,money):
        print("支付宝支付:%s"%money)

class WechatPay(Payment):
    def pay(self,money):
        print("微信支付:%s" % money)

class FactoryPay(metaclass=ABCMeta):
    @abstractmethod
    def create_factory(self):
        pass

class AliFactory(FactoryPay):
    def create_factory(self):
        return AliPay()

class WechatFactory(FactoryPay):
    def create_factory(self):
        return WechatPay()

f = WechatFactory()
p = f.create_factory()
p.pay(100)

  

工厂方法相比较简单工厂将每个具体的产品都对应一个具体工厂

抽象工厂模式

定义一个工厂接口,让工厂子类来创建一系列相关的对象;每个具体工厂都生产一套产品,强调一系列相关产品设计以便联合使用

角色:

  • 抽象工厂
  • 具体工厂
  • 抽象产品
  • 具体产品
  • 客户端

优点:

  • 将客户端与类的具体实现相分离
  • 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
  • 有利于产品的一致性

缺点:

  • 难以支持新种类产品
from abc import ABCMeta,abstractmethod

#抽象产品
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()

  

建造者模式

内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

角色:

  • 抽象建造者
  • 具体建造者
  • 指挥者
  • 产品

建造者模式与抽象工厂模式相似,也用来创建复杂对象;主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂着重于多个序列的产品对象

优点:

  • 隐藏了一个产品的内部结构和装配过程
  • 将构造代码与表示代码分开
  • 可以对构造过程进行更精细的控制
# coding : utf-8
# create by ztypl on 2017/5/25

from abc import abstractmethod, ABCMeta

#------产品------

class Player:
    def __init__(self, face=None, body=None, arm=None, leg=None):
        self.face = face
        self.arm = arm
        self.leg = leg
        self.body = body

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


#------抽象建造者------


class PlayerBuilder(metaclass=ABCMeta):
    @abstractmethod
    def build_face(self):
        pass
    @abstractmethod
    def build_arm(self):
        pass
    @abstractmethod
    def build_leg(self):
        pass
    @abstractmethod
    def build_body(self):
        pass
    @abstractmethod
    def get_player(self):
        pass

#--------具体建造者-----------

class BeautifulWomanBuilder(PlayerBuilder):
    def __init__(self):
        self.player = Player()
    def build_face(self):
        self.player.face = "漂亮脸蛋"
    def build_arm(self):
        self.player.arm="细胳膊"
    def build_body(self):
        self.player.body="细腰"
    def build_leg(self):
        self.player.leg="长腿"
    def get_player(self):
        return self.player

#--------指挥者----------

class PlayerDirector:
    def build_player(self, builder):
        builder.build_body()
        builder.build_arm()
        builder.build_leg()
        builder.build_face()
        return builder.get_player()


director = PlayerDirector()
builder = BeautifulWomanBuilder()
p = director.build_player(builder)
print(p)

  

创建型模式小结

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

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

适配器模式

内容:将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作

两种实现方式:

  • 类适配器:使用多继承
  • 对象适配器:使用组合
from abc import ABCMeta,abstractmethod

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

class WechatPay(Payment):
    def pay(self,money):
        print("微信消费%s"%money)

class AliPay(object):
    def huaqian(self,money):
        print("支付宝消费%s" % money)
#类适配
class ZhiFuPay(Payment,AliPay):
    def pay(self,money):
        return self.huaqian(money)

#对象适配
class Payadapter(Payment):
    def __init__(self,payment):
        self.payment= payment
    def pay(self,money):
        return self.payment.huaqian(money)


p = WechatPay()
p.pay(100)

p = Payadapter(AliPay())
p.pay(100)

p = ZhiFuPay()
p.pay(100)