设计模式:工厂方法模式
一、简单工厂模式
1、内容
不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例
关注的是对象创建的细节
2、角色
1、工厂角色(Factory)
class PaymentFactory: #工厂类 封装了对象创建的细节 def create_payment(self, method): if method == "alipay": return Alipay() elif method == "yuebao": return Alipay(True) elif method == "applepay": return ApplePay() else: raise NameError(method) f = PaymentFactory() p = f.create_payment("alipay") p.pay(100)
2、抽象产品角色(Product)
class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass
3、具体产品角色(Concrete Product)
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)
4、完整的代码
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 == "yuebao": return Alipay(True) elif method == "applepay": return ApplePay() else: raise NameError(method) f = PaymentFactory() p = f.create_payment("alipay") p.pay(100)
3、uml
4、优点
1、隐藏了对象创建的实现细节,客户端不需要修改代码
1、实现代码
class PaymentFactory: #工厂类 封装了对象创建的细节 def create_payment(self, method): if method == "alipay": return Alipay() elif method == "yuebao": return Alipay(True) elif method == "applepay": return ApplePay() else: raise NameError(method) f = PaymentFactory() p = f.create_payment("alipay") p.pay(100)
2、输出
"C:\Program Files\Python35\python.exe" F:/1_factory.py 支付宝支付100元 Process finished with exit code 0
5、缺点
违反了单一职责原则,将创建逻辑集中到一个工厂类里,当添加新产品时,需要修改工厂类代码,违反了开闭原则
6、案例
1、现在要加一个支付宝
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)
2、对用户隐藏细节
class PaymentFactory: def create_payment(self, method): if method == "alipay": return Alipay() elif method == "yuebao": return Alipay(True) elif method == "applepay": return ApplePay() else: raise NameError(method) f = PaymentFactory() p = f.create_payment("yuebao") p.pay(100) "C:\Program Files\Python35\python.exe" F:/1_factory.py 余额宝支付100元 Process finished with exit code 0
二、工厂方法模式
1、内容
定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
2、角色
1、抽象工厂角色(Creator)
class PaymentFactory(metaclass=ABCMeta): @abstractmethod def create_payment(self): pass
2、具体工厂角色(Concrete Creator)
class AlipayFactory(PaymentFactory): def create_payment(self): return Alipay() class ApplePayFactory(PaymentFactory): def create_payment(self): return ApplePay()
3、抽象产品角色(Product)
class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): pass
4、具体产品角色(Concrete Product)
class AlipayFactory(PaymentFactory): def create_payment(self): return Alipay() class ApplePayFactory(PaymentFactory): def create_payment(self): return ApplePay()
5、完成代码
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)
3、优点
1、每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
2、工厂类可以不知道它所创建的对象的类
3、隐藏了对象创建的实现细节
4、缺点
每增加一个具体产品类,就必须增加一个相应的具体工厂类
5、适用场景
1、需要生产多种、大量复杂对象的时候
2、需要降低耦合度的时候
3、当系统中的产品种类需要经常扩展的时候
6、uml类图
1、说明
1、三角:继承
2、虚线:是依赖
3、虚线圆圈:是注释
7、案例
1、如何创建
af = AlipayFactory() ali = af.create_payment() ali.pay(120) "C:\Program Files\Python35\python.exe" F:/2_factory_method.py 支付宝支付120元 Process finished with exit code 0
三、抽象工厂模式
1、内容
定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象
生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
2、角色
1、完整代码
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()
2、角色介绍
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
- 客户端(Client)
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
3、UML类图
4、缺点
难以支持新种类的(抽象)产品
3、优点
- 将客户端与类的具体实现相分离
- 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
- 有利于产品的一致性(即产品之间的约束关系)
4、应用场景
- 系统要独立于产品的创建与组合时
- 强调一系列相关的产品对象的设计以便进行联合使用时
- 提供一个产品类库,想隐藏产品的具体实现时
作者:罗阿红
出处:http://www.cnblogs.com/luoahong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。