Design 工厂方法模式
基本介绍
用户只需关注自身需要一个什么样的产品,需要从哪里去取,而不用将注意力放在如何构建这个产品上。
只要用户构思好了,直接从一个指定窗口中去拿产品即可。
特点:对外隐藏,每个工厂指定暴露一个接口,用于让用户取出该工厂的产品
乍一看和简单工厂模式很像,但是简单工厂模式是将多个产品指定暴露在一个工厂接口上。
而工厂方法模式则每个产品都有一个单独的工厂接口。
相较于简单工厂模式来说,设计更加简单一些。
同时,它们都属于普通工厂模式
案例图示
假如一个用户要买车,他只需要考虑车的品牌、颜色、还有喷漆等,除此之外还需要关注我从哪里买,但是不必关注造车的过程:
相较于普通的模式,省略了用户还需要通知厂商造车的环节:
相较于简单工厂模式,当有新的品牌加入时不需要修改统一买车店的源代码(因为已经移除了),直接添加厂商和专卖店即可,符合了开闭原则:
优缺点
优点:
- 每个具体产品都对应一个具体的工厂类,不需要修改工厂类代码
- 隐藏了对象创建的细节
缺点:
- 每增加一个具体产品类,就必须增加一个相应的具体工厂类
Python实现
用Python实现工厂方法模式:
#! /usr/local/bin/python3
# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod
# --------- 车的厂商相关 -----------
# 定义一个车工厂的抽象基类
class Car(metaclass=ABCMeta):
@abstractmethod
def build_car(self):
"""造车"""
pass
@abstractmethod
def get_car(self):
"""提车"""
pass
class Benz(Car):
"""奔驰"""
def __init__(self, name, color):
self.name = name
self.color = color
self.__result = None
def build_car(self):
self.__result = "一辆奔驰的车造好了,%s的车身上有一个炫酷的喷漆:%s" % (self.color, self.name)
def get_car(self):
return self.__result
class BMW(Car):
"""宝马"""
def __init__(self, name, color):
self.name = name
self.color = color
self.__result = None
def build_car(self):
self.__result = "一辆宝马的车造好了,%s的车身上有一个炫酷的喷漆:%s" % (self.color, self.name)
def get_car(self):
return self.__result
# --------- 专卖店相关 -----------
# 定义一个专卖店的抽象基类
class Shop(metaclass=ABCMeta):
"""每个专卖店都应该具有提车的功能"""
@abstractmethod
def get_car(self, name, color):
pass
class BenzShop(Shop):
"""奔驰专卖店"""
def get_car(self, name, color):
self.brand = Benz(name, color)
# 通知造车
self.brand.build_car()
# 通知取车
return self.brand.get_car()
class BMWShop(Shop):
"""宝马专卖店"""
def get_car(self, name, color):
self.brand = BMW(name, color)
# 通知造车
self.brand.build_car()
# 通知取车
return self.brand.get_car()
if __name__ == '__main__':
# 奔驰专卖店
benz_shop = BenzShop()
# 宝马专卖店
bmw_shop = BMWShop()
car01 = benz_shop.get_car("牛逼", "黑色")
print(car01)
car02 = bmw_shop.get_car("炫酷", "红色")
print(car02)
执行结果:
一辆奔驰的车造好了,黑色的车身上有一个炫酷的喷漆:牛逼
一辆宝马的车造好了,红色的车身上有一个炫酷的喷漆:炫酷
Golang实现
用Golang实现工厂方法模式:
....