工厂模式
一、工厂模式的优点
1.松耦合,即对象的创建可以独立于类的实现
2.客户端无需了解创建对象的类,但是可以照样使用它来创建对象,只需要知道需要传递的接口、方法和参数,就能够创建所需类型的对象。简化了客户端的实现
3.可以轻松地在工厂中添加其他类来创建其他类型的对象,无需更改客户端代码,有时客户端只需传递另一个参数就行
4.工厂还可以重用现有对象。但是,如果客户端直接创建对象的话,总是创建一个新对象
二、工厂模式
*、简单工厂模式:允许接口创建对象,但不会暴露对象的创建逻辑
*、工厂方法模式:允许接口创建对象,但使用哪个类来创建对象,则是由子类决定的
*、抽象工厂模式:是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口,该模式能够提供其他工厂的对象,在其内部 创建其他对象
1、简单工厂模式
UML如下
示例代码如下:
# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def do_say(self):
pass
class Dog(Animal):
def do_say(self):
print("dog bhow bhow")
class Cat(Animal):
def do_say(self):
print("cat meow meow")
class ForestFactory(object):
def make_sound(self, object_type):
return eval(object_type)().do_say()
if __name__ == '__main__':
ff = ForestFactory()
animal = input("which animal should make_sound Dog or Cat?")
ff.make_sound(animal)
创建一个为Animal的抽象产品,带有方法do_say(),利用Animal接口创建了两种产品(Dog,Cat),并实现了do_say方法来提供这些动物相应的叫声。ForestFactory是一个带有make_sound()方法的工厂,根据客户端传递的参数类型,可以在运行时创建适当的Animal实例,并输出正确的声音。
2、工厂方法模式
1.了解工厂方法模式
*、定义了一个接口来创建对象,但是工厂本身并不复杂创建对象,而是将这一任务交由子类来完成,即子类决定了要实例化哪些类
*、Factory方法的创建是通过继承而不是实例化来完成的
*、工厂方法使设计更加具有可定制性,它可以返回相同的实例或子类,而不是某种类型的对象
UML如下:
在该UML中,有一个包含factoryMethod()方法的抽象类Creator,factoryMethod()方法负责创建指定类型的对象。ConcreteCreator类提供了一个实例Creator抽象类的factoryMethod()方法,这种方法可以在运行时修改已创建的对象。ConcreteCreator创建ConcreteProduct,并确保其创建的对象实现了Product,同时为Product接口中的所有方法提供相应的实现。
简言之,Creator接口的factoryMethod()方法和ConcreteCreator类共同决定了要创建Product的哪个子类。因此,工厂方法模式定义了一个接口来创建对象,但具体实例化哪个类则是由它的子类决定的。
2.实现工厂方法
# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod
# 接口Product
class Section(metaclass=ABCMeta):
@abstractmethod
def describe(self):
pass
# 定义多个ConcreteProduct
class PersonalSection(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")
# 创建了一个抽象类(Creator) Profile,提供了一个工厂方法createProfile()
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)
# 创建了两个ConcreteCreator,即linkedin, facebook,每个类都实现了createProfile抽象方法,
# 由该方法在运行时实际创建(实例化)多个区(ConcreteProduct)
class linkedin(Profile):
def createProfile(self):
self.addSections(PersonalSection())
self.addSections(PatentSection())
self.addSections(PublicationSection())
class facebook(Profile):
def createProfile(self):
self.addSections(PersonalSection)
self.addSections(AlbumSection)
# 客户端代码
if __name__ == '__main__':
profile_type = input("which profile LinkedIn or FaceBook?")
profile = eval(profile_type.lower())()
print("creating profile..", type(profile).__name__)
print("profile has sections --", profile.getSections())
上述代码段的输出如下:
3、工厂方法模式的优缺点
ConcreteProduct类
b、它们是松耦合的,创建对象的代码与使用它们的代码的分开的。客户端完全不用关心要传递哪些参数以及需要实例化哪些类。由于添加新类更加容易,降低了维护成本。
3、抽象工厂方法模式
1、了解抽象工厂模式
抽象工厂的主要目的是提供一个接口来创建一系列相关对象,而无需指定具体的类。工厂方法将创建实例的任务委托给了子类,而抽象工厂方法的目标是创建一系列相关对象。
2、UML
在该UML中,ConcreteFactory1和ConcreteFactory2是通过AbstractFactory接口创建的,并创建实例ConcreteProduct1和ConcreteProduct2、AnotherConcreteProduct1和 AnotherConcreteProduct2;ConcreteProduct1和ConcreteProduct2是通过AbstractProduct接口创建的,而AnotherConcreteProduct1和AnotherConcreteProduct2则是通过 AnotherAbstractProduct接口创建的。
实际上,抽象工厂模式不仅确保客户端与对象的创建相互隔离,同时还确保客户端能够使用创建的对象。但是,客户端只能通过接口访问对象。
3、实现抽象工厂模式
# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod
# AbstractFactory
class PizzaFactory(metaclass=ABCMeta):
# 具有两个抽象方法,它们需要通过ConcreteFactory实现
@abstractmethod
def creatVegPizza(self):
pass
@abstractmethod
def creatNonVegPizza(self):
pass
# 两个ConcreteFactory,实现了抽象方法
class IndianPizzaFactory(PizzaFactory):
def creatVegPizza(self):
return DeluxVeggiePizza()
def creatNonVegPizza(self):
return ChickenPizza()
class USPizzaFactory(PizzaFactory):
def creatVegPizza(self):
return MexicanVegPizza()
def creatNonVegPizza(self):
return HamPizza()
# 定义抽象类AbstractProduct
class VegPizza(metaclass=ABCMeta):
@abstractmethod
def prepare(self, VegPizza):
pass
# 定义抽象类AnotherAbstractProduct
class NonVegPizza(metaclass=ABCMeta):
@abstractmethod
def serve(self, VegPizza):
pass
# 定义ConcreteProduct1
class DeluxVeggiePizza(VegPizza):
def prepare(self):
print("prepare", type(self).__name__)
# 定义ConcreteProduct2
class ChickenPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, "is served with chicken on", type(VegPizza).__name__)
# AnotherConcreteProduct1
class MexicanVegPizza(VegPizza):
def prepare(self):
print("prepare", type(self).__name__)
# AnotherConcreteProduct2
class HamPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, "is served with chicken 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.creatNonVegPizza()
self.VegPizza = self.factory.creatVegPizza()
self.VegPizza.prepare()
self.NonVegPizza.serve(self.VegPizza)
if __name__ == '__main__':
pizza = PizzaStore()
pizza.makePizzas()
运行结果如下:
工厂方法与抽象工厂对比: