3.python设计模式【工厂模式】

1.简单工厂模式

  • 内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品的实例。
  • 角色:
    • 工厂角色(creator)
    • 抽象产品角色(product)
    • 具体产品角色
  • UML图 :
    在这里插入图片描述
  • 举个例子:
    需求:现在需要选择支付,可以花呗支付、支付宝余额支付、微信支付,但是客户端只需要直接调用支付方法,不需要实现具体的细节。
from abc import ABCMeta, abstractmethod
# 抽象类
class Payment(metaclass=ABCMeta):
    @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("支付宝余额支付" % 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 name %s" % method)


# client
# 这样就隐藏了内部实现,客户端只需要直接调用支付方法就可以直接支付,不需要关注实现细节
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(100)
  • 优点
    • 隐藏了对象创建的实现细节
    • 客户端不需要修改代码
  • 缺点:
    • 违反了单一职责原则,将创建逻辑集中到一个工厂类里
    • 当添加新产品时候,需要修改工厂类代码,违反了开闭原则

2.工厂方法模式

  • 内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类
  • 角色:
    • 抽象工厂角色(creator)
    • 具体工厂角色(concrete creator)
    • 抽象产品角色(product)
    • 具体产品角色(concrete product)
    • 客户端(Client)
  • UML图:
    在这里插入图片描述
  • 举个例子:
    需求:现在需要选择支付,可以花呗支付、支付宝余额支付、微信支付,但是客户端只需要直接调用支付方法,添加银行卡支付类,但是要求不能修改原来的代码(符合开闭原则)
from abc import ABCMeta, abstractmethod
# 抽象类
class Payment(metaclass=ABCMeta):
    @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("支付宝余额支付" % 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 HuabeiPayFactory(PaymentFactory):
    def create_payment(self):
        return AliPay(use_huabei=True)

class BankPayFactory(PaymentFactory):
    def create_payment(self):
        return BankPay()

# client
pf=BankPayFactory()
p=pf.create_payment()
p.pay(100)
  • 优点:
    • 每个具体的产品都对应一个具体工厂类,不需要修改工厂类代码
    • 隐藏了对象创建的细节
  • 缺点:
    • 每增加一个具体的产品类,就必须增加一个相应的具体工厂类,代码有很大冗余

3.抽象工厂模式

  • 内容:定义一个工厂类接口,让工厂类来创建一系列相关或相互依赖的对象。相比工厂方法模式,抽象工厂模式的每个具体工厂都生产一套产品
  • 角色:
    • 抽象工厂角色(creator)
    • 具体工厂角色(concrete creator)
    • 抽象产品角色(product)
    • 具体产品角色(concrete product)
    • 客户端(Client)
  • UML图
    在这里插入图片描述
  • 举个例子:
    需求:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
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("苹果手机壳")

# cpu
class SnapDragonCPU(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 Harmony(OS):
    def show_os(self):
        print("Harmony系统")

# --------------具体工厂--------------------
class MiFactory(PhoneFactory):
    def make_shell(self):
        return BigShell()

    def make_cpu(self):
        return SnapDragonCPU()

    def make_os(self):
        return Android()

class HuaweiFactory(PhoneFactory):
    def make_shell(self):
        return BigShell()

    def make_cpu(self):
        return MediaCPU()

    def make_os(self):
        return Harmony()


class iphoneFactory(PhoneFactory):
    def make_shell(self):
        return AppleShell()

    def make_cpu(self):
        return AppleCPU()

    def make_os(self):
        return IOS()

# --------------客户端--------------------
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()

输出结果:
--------手机信息--------
苹果CPU
IOS系统
苹果手机壳

  • 优点:
    • 将客户端与类的具体实现相分离
    • 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
    • 有利于产品的一致性(即产品之间的约束关系)
  • 缺点:
    • 难以支持新种类的(抽象)产品
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值