公司生产产品时会涉及到公司和产品的对应关系,比如A公司生产A产品,B公司生产B产品,等到公司生产完产品后工可能还要提供相应的服务,可能过了一段时间公司规模变大,将会生产更多的产品和提供更多的服务。我举这个栗子是为了说明软件需求是一个动态变化的过程,如果每一次需求的改变都要重构整个软件工程,那必定是一场灾难。正如设计模式的开放封闭原则所述:
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
软件实体(类、模块、函数等)应对扩展开放,但对修改封闭。
当我们慢慢领悟到“抽象”这种思想时,我们写出来的代码将不再局限于具体类,“万物皆可抽象”,当我们站在更高的维度俯视整个软件架构时,为修改需求疲于奔命的日子也将一去不复返。
工厂模式就是将工厂类和产品类分开,工厂和产品刚开始并不知道彼此的对应关系(抽象出来),只有等到具体的公司确定要生产的具体产品,这中对应关系才产生。所以工厂模式包含四种角色:抽象工厂、具体工厂、抽象产品、具体产品。
抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用接口或者抽象类实现,而所有的具体工厂类必须实现这个接口或继承这个抽象类。具体工厂类(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。实际应用中使用具体类来实现这个角色。抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用接口或者抽象类来实现这一角色。具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。实际应用中使用具体类来实现这个角色。
而工厂模式又可细分为简单工厂模式、工厂方法模式和抽象工厂模式三种。说了这么多理论,不如直接来看代码(python实现)。
# -*- coding: utf-8 -*- """ Created on Thu Apr 13 09:57:07 2017 @author: acelit """ #简单工厂模式 #抽象产品类 class Product(): def __init__(self): self.productType = '' def getProductType(self): raise NotImplementedError('Product') def doUse(self): raise NotImplementedError('Product') #具体产品类 class ProductA(Product): def __init__(self): self.productType = 'ProductA' self.productParameter = 'A' def getProductType(self): return self.getProductType def getParameter(self): return self.productParameter def doUse(self): print '这是ProductA实现的功能' class ProductB(Product): def __init__(self): self.productType = 'ProductB' self.productParameter = 'B' def getProductType(self): return self.getProductType def getParameter(self): return self.productParameter def doUse(self): print '这是ProductB实现的功能' #抽象工厂类 class Company(): def makeProduct(self, parameter): raise NotImplementedError('Factory') #具体工厂类 class CompanyX(Company): def __init__(self): self.product = '' def makeProduct(self, parameter): if parameter == 'A': self.product = ProductA() return self.product if parameter == 'B': self.product = ProductB() return self.product else: return None #测试 def main(): product = CompanyX().makeProduct('A') product.doUse() product = CompanyX().makeProduct('B') product.doUse() if __name__ == '__main__': main()
简单工厂模式的特点是在具体工厂类中通过产品的参数判断来决定生产何种产品,这会导致每次新增加一种产品都需要在具体工厂类中修改相应的判断条件。这不符合开放封闭原则。
场景:公司X处于扩张期,打算专注核心产品A的生产,将产品B独立到旗下的子公司Y生产。
# -*- coding: utf-8 -*- """ Created on Thu Apr 13 09:57:07 2017 @author: acelit """ #工厂方法模式 #抽象产品类 class Product(): def __init__(self): self.productType = '' def getProductType(self): raise NotImplementedError('Product') def doUse(self): raise NotImplementedError('Product') #具体产品类 class ProductA(Product): def __init__(self): self.productType = 'ProductA' def getProductType(self): return self.getProductType def doUse(self): print '这是ProductA实现的功能' class ProductB(Product): def __init__(self): self.productType = 'ProductB' def getProductType(self): return self.getProductType def doUse(self): print '这是ProductB实现的功能' #抽象工厂类 class Company(): def makeProduct(self): raise NotImplementedError('Factory') #具体工厂类 #公司X生产产品A class CompanyX(Company): def __init__(self): self.product = '' def makeProduct(self): self.product = ProductA() return self.product #公司Y生产产品B class CompanyY(Company): def __init__(self): self.product = '' def makeProduct(self): self.product = ProductB() return self.product #测试 def main(): product = CompanyX().makeProduct() product.doUse() product = CompanyY().makeProduct() product.doUse() if __name__ == '__main__': main()
工厂方法模式将具体产品类对应到具体工厂类,避免了具体工厂类中的产品判断,进一步将工厂和产品去耦合。
# -*- coding: utf-8 -*- """ Created on Thu Apr 13 09:57:07 2017 @author: acelit """ #抽象工厂模式 #抽象产品类 class Product(): def __init__(self): self.productType = '' def getProductType(self): raise NotImplementedError('Product') def doUse(self): raise NotImplementedError('Product') #具体产品类 class ProductA(Product): def __init__(self): self.productType = 'ProductA' def getProductType(self): return self.getProductType def doUse(self): print '这是ProductA实现的功能' class ProductB(Product): def __init__(self): self.productType = 'ProductB' def getProductType(self): return self.getProductType def doUse(self): print '这是ProductB实现的功能' #抽象服务类 class Service(): def __init__(self): self.serviceType = '' def getServiceType(self): raise NotImplementedError('Service') def doServer(self): raise NotImplementedError('Service') #具体服务类 class ServiceA(Service): def __init__(self): self.serviceType = 'ServiceA' def getServiceType(self): return self.serviceType def doServer(self): print '这是ServiceA提供的服务' class ServiceB(Service): def __init__(self): self.serviceType = 'ServiceB' def getServiceType(self): return self.serviceType def doServer(self): print '这是ServiceB提供的服务' #抽象工厂类 class Company(): def makeProduct(self): raise NotImplementedError('Company') def makeServer(self): raise NotImplementedError('Company') #具体工厂类 #公司X生产产品A、提供服务A class CompanyX(Company): def __init__(self): self.product = '' self.service = '' def makeProduct(self): self.product = ProductA() return self.product def makeServer(self): self.service = ServiceA() return self.service #公司Y生产产品B、提供服务B class CompanyY(Company): def __init__(self): self.product = '' self.service = '' def makeProduct(self): self.product = ProductB() return self.product def makeServer(self): self.service = ServiceB() return self.service #测试 def main(): product = CompanyX().makeProduct() service = CompanyX().makeServer() product.doUse() service.doServer() product = CompanyY().makeProduct() service = CompanyY().makeServer() product.doUse() service.doServer() if __name__ == '__main__': main()
抽象工厂模式更加灵活,抽象工厂类可继续拓展不同产品的接口,只要在具体工厂类中对应新的产品即可。
以上。
ref: http://blog.csdn.net/wuzhekai1985/article/details/6660462
