设计模式之工厂模式

  工厂模式是设计模式中的经典模式,工厂模式又可分为以下三种类型:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

这三种模式可以理解为同一种编程思想的三个版本,从简单到高级不断升级。本文将着重介绍简单工厂模式

简单工厂模式

  简单工厂模式(Simple Factory Pattern)指的是专门定义一个类来负责创建其它类的实例,根据参数的不同创建不同类的实例,被创建的实例通常具有共同的父类。简单工厂模式又被称为静态工厂方法模式
  我们介绍一种最简单的简单工厂模式版本,只有一个工厂类SimpleFactory,类中有一个静态创建方法createProduct,该方法根据参数的名称(name)来创建具体的产品(子类)对象,其UML类图如下:
设计模式之工厂模式_第1张图片
  让我们来看一个例子,比如我们有一个工厂(ToyFactory),需要根据玩具的名称,来加工出玩具鸭子(DuckToy)、玩具椅子(ChairToy)、玩具火车(TrainToy),其UML类图如下:
设计模式之工厂模式_第2张图片
  Python实现代码:

# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod


# 玩具抽象类
class Toy(metaclass=ABCMeta):
    def __init__(self, name, price):
        self.__name = name
        self.__price = price

    def getName(self):
        return self.__name

    def getPrice(self):
        return self.__price

    @abstractmethod
    def getMaterial(self):
        pass


# 玩具鸭子
class DuckToy(Toy):
    def __init__(self, name, price):
        super(DuckToy, self).__init__(name, price)

    def getMaterial(self):
        return 'cotton'


# 玩具椅子
class ChairToy(Toy):
    def __init__(self, name, price):
        super(ChairToy, self).__init__(name, price)

    def getMaterial(self):
        return 'wood'


# 玩具火车
class TrainToy(Toy):
    def __init__(self, name, price):
        super(TrainToy, self).__init__(name, price)

    def getMaterial(self):
        return 'metal'


# 玩具加工类
class ToyFactory:
    def make_toy(self, toy_name):
        if toy_name == 'duck':
            toy = DuckToy('Duck', 20.0)
        elif toy_name == 'chair':
            toy = ChairToy('Chair', 50.0)
        elif toy_name == 'train':
            toy = TrainToy('Train', 100.0)
        else:
            raise ValueError('unsupported toy name, please choose duck, chair, train.')
        return toy


if __name__ == '__main__':
    duck_toy = ToyFactory().make_toy('duck')
    print('make a %s toy, its material: %s, its price: %s' % (duck_toy.getName(), duck_toy.getMaterial(), duck_toy.getPrice()))
    chair_toy = ToyFactory().make_toy('chair')
    print('make a %s toy, its material: %s, its price: %s' % (chair_toy.getName(), chair_toy.getMaterial(), chair_toy.getPrice()))
    train_toy = ToyFactory().make_toy('train')
    print('make a %s toy, its material: %s, its price: %s' % (train_toy.getName(), train_toy.getMaterial(), train_toy.getPrice()))

运行结果:

make a Duck toy, its material: cotton, its price: 20.0
make a Chair toy, its material: wood, its price: 50.0
make a Train toy, its material: metal, its price: 100.0

在该例子中,SimpleFactory为ToyFactory,方法make_toy根据玩具名称来加工不同的玩具类型,当玩具名称为duck时,加工玩具鸭子(DuckToy);当玩具名称为chair时,加工玩具椅子(ChairToy);当玩具名称为train时,加工玩具火车(TrainToy)。
  简单工厂模式的优点为:

  • 实现简单,结构清晰
  • 抽象出一个专门的类来负责某类对象的创建,分割出创建的职责,不能直接创建具体的对象,只需传入适当的参数即可
  • 使用者可以不关注具体对象的类名称,只需知道传入什么参数可以创建哪些需要的对象

其缺点为:

  • 不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑,不符合“开放-封闭”原则
  • 当产品类型较多时,工厂的创建逻辑可能过于复杂

工厂方法模式

  工厂方法模式简单工厂模式的一个升级版本,其含义为定义一个创建对象(实例化对象)的接口,让子类来决定创建哪个类的实例。工厂方法使一个类的实例化延迟到其子类。
  为解决上述简单工厂模式不符合“开放-封闭”原则,我们对SimpleFactory进行拆分,抽象出一个父类Factory,并增加多个子类分别负责创建不同的具体产品,其UML类图如下:
设计模式之工厂模式_第3张图片
工厂方法模式的优点为:

  • 解决了简单工厂模式不符合“开放-封闭”原则的问题,使程序更容易拓展
  • 实现简单

其缺点为:

  • 对于有多种分类的产品,或具有二级分类的产品,工厂方法模式不再适用

抽象工厂模式

  抽象工厂模式工厂方法模式的升级版本,可以解决具有二级分类的产品的创建问题,其UML类图可以设计如下:
设计模式之工厂模式_第4张图片
抽象工厂模式的优点为:

  • 解决了具有二级分类的产品的创建

其缺点为:

  • 如果产品分类超过二级,则该模式会变得臃肿
  • 不能解决产品有多种分类、多种组合的问题

参考文献

  1. 罗伟富 人人都懂设计模式:从生活中领悟设计模式(Python实现)[B],电子工业出版社

你可能感兴趣的:(设计模式,设计模式)