面向对象的设计模式1

创建型模式

1.简单的工厂模式

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

角色:

  ■工厂角色(Creator)

  ■抽象产品角色(Product)

  ■具体产品角色(Concrete Product)

优点:

  ■隐藏了对象的创建细节

  ■客户端不需要修改代码

缺点:

  ■违反了单一职责的原则,将创建逻辑集中到一个工厂类里

  ■当添加新产品时,需要修改工厂类代码,违反开闭原则

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 WechatPay(Payment):
    def pay(self, money):
        print("微信支付%s元"%money)



payment = Alipay()
payment.pay(100)

 

 

2.工厂方法模式

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

适用场景:

  ■需要生产多种,大量复杂对象的时候

  ■需要降低耦合度的时候

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

优点:

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

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

缺点:

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

from abc import abstractmethod, ABCMeta


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


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 == "applepay":
            return ApplePay()
        elif method == "yuebao":
            return Alipay(True)
        else:
            raise NameError(method)

factory = PaymentFactory()
payment = factory.create_payment("yuebao")
payment.pay(100)

3.抽象工厂模式

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

区别:相比于其他工厂模式,抽象工厂模式中每个具体工厂都生产一套产品

适用场景:

  ■系统要独立产品的创建和组合时

  ■强调一系类相关的产品对象的设计以便进行联合使用时

  ■提供一个产品类库,想隐藏产品的具体实现时

优点:

  ■将客户端与类的具体实现相分离

  ■每个工厂创建了一个完整的产品系列,使得易于交换产品系列

  ■有利于产品的一致性

  

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

4.建造者模式

内容:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
角色:
  抽象建造者(Builder)
  具体建造者(Concrete Builder)
  指挥者(Director)
  产品(Product)

建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列的产品对象。
适用场景:
  当创建复杂对象的算法(Director)应该独立于该对象的组成部分以及它们的装配方式(Builder)时
  当构造过程允许被构造的对象有不同的表示时(不同Builder)。
优点:
  隐藏了一个产品的内部结构和装配过程
  将构造代码与表示代码分开
  可以对构造过程进行更精细的控制

 

import random
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 RandomPlayerBuilder(PlayerBuilder):
    def __init__(self):
        self.player = Player()
    def build_face(self):
        self.player.face = random.choice(["瓜子脸","西瓜子脸"])
    def build_arm(self):
        self.player.arm=random.choice(["长胳膊","短胳膊"])
    def build_body(self):
        self.player.body=random.choice(["苗条",""])
    def build_leg(self):
        self.player.leg=random.choice(["长腿","短腿"])
    def get_player(self):
        return self.player

class PlayerDirector:
    def __init__(self, builder):
        self.builder = builder
    # 控制组装顺序
    def build_player(self):
        self.builder.build_body()
        self.builder.build_face()
        self.builder.build_arm()
        self.builder.build_leg()
        return self.builder.get_player()




pd = PlayerDirector(RandomPlayerBuilder())
p = pd.build_player()
print(p)

5.单例模式

from abc import abstractmethod, ABCMeta

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


class MyClass(Singleton):
    def __init__(self, name=None):
        if name is not None:
            self.name = name


a = MyClass("a")

print(a)
print(a.name)

b = MyClass("b")

print(b)
print(b.name)

print(a)
print(a.name)

创建型模式小结:

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

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

 

posted @ 2018-02-02 19:12  TAMAYURA  阅读(163)  评论(0编辑  收藏  举报