1、工厂设计模式优点
1.1、松耦合,即对象的创建可以独立于类的实现。
1.2、客户端无需了解创建对象的类,但是照样可以使用它出港件对象。它只需要知道需要传递的接口、方法、参数,就能够创建所需的对象了。这样简化了客户端的实现
1.3、可以轻松地在工厂中添加其他的类来创建其他类型的对象,而这无需更改客户端的代码。最简单的情况下,客户端只需要传递一个参数就可以了。
1.4、工厂还可以重用现有的对象。但是,如果客户端直接创建对象的话,总是创建一个新的对象。
2、简单工厂模式
2.1、允许接口创建对象,但不会暴露对象的创建逻辑。
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def do_say(self):
pass
class Dog(Animal):
def do_say(self):
print('Wang Wang!')
class Cat(Animal):
def do_say(self):
print('Miao Miao!')
class AnimalSimpleFactory:
def make_sound(self, animal_type):
return eval(animal_type)().do_say()
if __name__ == '__main__':
asf = AnimalSimpleFactory()
animal = input('which animal should make_sound Cat or Dog?')
asf.make_sound(animal)
3、工厂方法模式
3.1、允许接口创建对象,但是使用哪个类来创建对象,则是交由子类来决定的。
3.2、factory方法的创建是通过继承而不是实例化完成的。
3.3、工厂方法使设计更具有可定制性。它可以返回相同的实例或子类,而不是某中类型的对象。
from abc import ABCMeta, abstractmethod
class Section(metaclass=ABCMeta):
@abstractmethod
def describe(self):
pass
class PersonSection(Section):
def describe(self):
print("personal section")
class AlbumSection(Section):
def describe(self):
print("Album section")
class PatentSection(Section):
def describe(self):
print("Patent section")
class PublicationSection(Section):
def describe(self):
print("Publication section")
创建一个抽象类, 并提供一个工厂方法:
class Profile(metaclass=ABCMeta):
def __init__(self):
self.sections = []
self.createProfile()
@abstractmethod
def createProfile(self):
pass
def getSections(self):
return self.sections
def addsections(self, section):
self.sections.append(section)
class Zhihu(Profile):
def createProfile(self):
self.addsections(PersonSection())
self.addsections(AlbumSection())
self.addsections(PublicationSection())
class Csdn(Profile):
def createProfile(self):
self.addsections(PatentSection())
self.addsections(PersonSection())
if __name__ == '__main__':
profile_type = input("which profile you'd like to create (Zhihu or Csdn)")
profile = eval(profile_type)()
print("create profile..", type(profile).__name__)
print("Profile has sections --", profile.getSections())
输出结果
which profile you'd like to create (Zhihu or Csdn) Zhihu
create profile.. Zhihu
Profile has sections --
[<__main__.PersonSection object at 0x0000020CA7C4BCF8>,
<__main__.AlbumSection object at 0x0000020CA7C4BD30>,
<__main__.PublicationSection object at 0x0000020CA7C4BD68>]
3.4、优点:
3.4.1、他具有更大的灵活性,使得代码更加通用,因为他不是单纯的实例化某个类。这样实现哪个类取决于接口。
3.4.2、它们是松耦合的,因为创建对象的代码和使用它的代码是分开的。客户端完全不需要关心传递哪些参数以及需要实例化哪些类。由于添加新的类更加容易,所以降低了维护成本。
4、抽象工厂模式
4.1、抽象工厂模式主要目的是提供一个接口来创建一系列的相关对象,而无需制定具体的类,工厂方法将创建实例的任务委托给了子类,而抽象工厂模式目标是创建一系列的相关对象。
from abc import ABCMeta, abstractmethod
class PizzaFactory(metaclass=ABCMeta):
@abstractmethod
def createVegPizza(self):
pass
@abstractmethod
def createNonVegPizza(self):
pass
class IndianPizzaFactory(PizzaFactory):
def createVegPizza(self):
return DeluxVeggiePizza()
def createNonVegPizza(self):
return ChickenPizza()
class USPizzaFactory(PizzaFactory):
def createVegPizza(self):
return MexicanVegPizza()
def createNonVegPizza(self):
return HamPizza()
class VegPizza(metaclass=ABCMeta):
@abstractmethod
def prepare(self, VegPizza):
pass
class NonVegPizza(metaclass=ABCMeta):
@abstractmethod
def serve(self, VegPizza):
pass
class DeluxVeggiePizza(VegPizza):
def prepare(self):
print("Prepare ", type(self).__name__)
class ChickenPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, " is served with Chicken on ", type(VegPizza).__name__)
class MexicanVegPizza(VegPizza):
def prepare(self):
print("Prepare ", type(self).__name__)
class HamPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, " is served with Ham on ", type(VegPizza).__name__)
class PizzaStore:
def __init__(self):
pass
def makePizzas(self):
for factory in [IndianPizzaFactory(), USPizzaFactory()]:
self.factory = factory
self.NonVegPizza = self.factory.createNonVegPizza()
self.VegPizza = self.factory.createVegPizza()
self.VegPizza.prepare()
self.NonVegPizza.serve(self.VegPizza)
pizza = PizzaStore()
pizza.makePizzas()
输出结果:
Prepare DeluxVeggiePizza
ChickenPizza is served with Chicken on DeluxVeggiePizza
Prepare MexicanVegPizza
HamPizza is served with Ham on MexicanVegPizza
5、工厂方法模式和抽象工厂模式区别
5.1、工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
5.2、工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。