设计模式:简单工厂模式、工厂模式、抽象工厂模式
简单工厂模式
创建对象放在了工厂类中,而不是再暴露在外边,通过工厂类实现所有操作。
内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责返回创建产品类的实例。
角色:
工厂角色(Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
优点:
隐藏了对象创建的实现细节,工厂根据条件产生不同功能的类。
客户端不需要修改代码
缺点:
违反了单一职责原则:将创建逻辑几种到一个工厂类里
违反了开闭原则: 当添加新产品时,需要修改工厂类代码,对修改打开了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from abc import abstractmethod, ABCMeta #定义支付方法的抽象类 class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass #定义不同的支付方法 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(enable_yuebao=True) else: raise NameError(method) f = PaymentFactory() p = f.create_payment("alipay") p.pay(100) 简单工厂模式
#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @Author: Victor @Contact: ycyj@163.com @Date: 2020/8/20 @function: '' ''' import abc import math # 抽象现金类, 父类 class cash(): # 抽象类,子类必须实现该类 @abc.abstractmethod def acceptCash(self, money): pass # 正常收费类, 子类 class cashNormal(cash): def acceptCash(self, money): return money # 打折收费类, 子类 class cashRebate(cash): # 打折数 moneyRebat = 0 def __init__(self, moneyRebate): self.moneyRebate = moneyRebate def acceptCash(self, money): return float(money) * float(self.moneyRebate) # 满减收费类, 子类 class cashReturn(cash): # 满足金额 moneyCondition = 0 # 返利 moneyReturn = 0 def __init__(self, conditionPirce, moneyReturn): self.conditionPirce = conditionPirce self.moneyReturn = moneyReturn def acceptCash(self, money): money = float(money) if money >= self.conditionPirce: money = money - self.moneyReturn return money # 优惠工厂类 class createCashActivityFactory(): @staticmethod def exeActivity(cashType): cash = None # 这里可以添加其他运算方法 if cashType == "无折扣": cash = cashNormal() elif cashType == "满300减100": cash = cashReturn(300, 100) elif cashType == "打8折": cash = cashRebate(0.8) else: pass return cash if __name__ == "__main__": print("请输入消费金额:") price = input() print("请输入优惠类型:") type = input() factory = createCashActivityFactory.exeActivity(type) print("消费总金额:", factory.acceptCash(price))
工厂方法模式
具体工厂依赖具体产品
内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
角色:
抽象工厂角色(Creator)
具体工厂角色(Concrete Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。
这个模式和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。
适用场景:
需要生产多种、大量复杂对象的时候
需要降低耦合度的时候
当系统中的产品种类需要经常扩展的时候
优点:
每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
隐藏了对象创建的实现细节
缺点:
每增加一个具体产品类,就必须增加一个相应的具体工厂类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 PaymentFactory(metaclass=ABCMeta): @abstractmethod def create_payment(self): pass #继承工厂抽象类,具体工厂负责具体的产品 class AlipayFactory(PaymentFactory): def create_payment(self): return Alipay() class ApplePayFactory(PaymentFactory): def create_payment(self): return ApplePay() #具体使用,利用具体工厂的对象 实例 具体支付的对象 然后 调用支付方法 # 用户输入 # 支付宝,120 af = AlipayFactory() ali = af.create_payment() ali.pay(120) 工厂方法模式
抽象工厂模式
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用性:
一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当你要强调一系列相关的产品对象的设计以便进行联合使用时。
当你提供一个产品类库,而只想显示它们的接口而不是实现时。
内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
角色:
抽象工厂角色(Creator)
具体工厂角色(Concrete Creator)
抽象产品角色(Product)
具体产品角色(Concrete Product)
客户端(Client)
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
适用场景:
系统要独立于产品的创建与组合时
强调一系列相关的产品对象的设计以便进行联合使用时
提供一个产品类库,想隐藏产品的具体实现时
优点:
将客户端与类的具体实现相分离
每个工厂创建了一个完整的产品系列,使得易于交换产品系列
有利于产品的一致性(即产品之间的约束关系)
缺点:
难以支持新种类的(抽象)产品
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(HuaweiFactory()) p1.show_info() 抽象工厂模式
重点:简单工厂, 工厂,抽象工厂的区别和联系