工厂模式 Factory
1.1 概述
简单工厂模式:简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。它定义一个工厂类,它可以根据参数的不同返回不同的实例,被创建的实例通常都具有共同的父类。
简单工厂模式在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。简单工厂模式结构比较简单,其核心是工厂类的设计。简单来说,就是我传一个参数(男、女、人妖)进去,可以创建对应性别的人出来。
1.2 运用
简单工厂模式的角色:
-
Product(抽象产品类):一般是一个抽象类或是接口
-
ConcreteProduct(具体产品类):实现或是继承 Product
-
Factory(工厂类):用来创建具体的产品
场景描述:我去商店买菜,结果老板跟我说,你要什么自己去拿吧(工厂类Factory),那也就是,我想要什么这个动作,就是我们传参数进去来得到某个东西。
Product类
ConcreteProduct类
Factory类
商店
test:
1.3 总结
简单工厂模式中工厂类的职责太重,一旦不能工作将影响整个系统,且如果添加过多的产品,工厂类中的逻辑就过于复杂。所以简单工厂模式适用于逻辑简单,且需要创建对象较少的情况。简单来说,在Factory中太多逻辑判断来生成对象,就会过于复杂,不容易维护啦!!
工厂方法模式
2.1 概述
上面的简单工厂模式,如果这时候增加一个新的食物“水果”,那么我们就要修改工厂类 FoodsFactory中的 create 函数。这是违反了设计模式中的开放封闭原则的,这样一直修改也是说明代码扩展能力不够。所以就有了工厂方法模式,来解决这些问题。
工厂方法模式与简单工厂不同地方在于,把工厂类抽象出一个父类。创建对象的事情交给其具体子类工厂完成。
2.2 运用
比简单工厂新增一个角色:
-
ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
FoodsFactory 抽象成父类,提供create函数,但是不参与具体逻辑
ConcreteFactory 类
修改 shop 类
test:
2.3 总结
工厂方法模式是对简单工厂模式的升级应用,它解决了简单工厂模式中工厂类职责繁重的问题,且更符合设计模式的开闭原则,增加新的产品不需要修改原先的代码,只需要增加对应的产品实例及工厂实例即可,同时这也是工厂方法模式的一个缺点,添加新产品,系统中的类就需要成对的增加,一定程度上增加了系统的复杂度。简单来说,添加一个新的产品就要创建一个对应的工厂类,这样的话,复杂程度会加大。
抽象工厂模式
3.1 概述
工厂方法模式通过引入产品工厂,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。这时候,我们可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产。
抽象工厂模式定义是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。
与简单工厂或工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。
如上图所示,简单工厂模式及工厂方法模式解决的都只是一种产品的创建过程,而在现实中,一个工厂往往不仅仅生产一种产品,例如日本可能同时生产牛肉、生菜、苹果等产品,这里我们就需要对于一个产品族创建一个抽象工厂,在这个在具体的某一个产品族的工厂中创建具体的产品。
如上例中,若用工厂方法模式,则需要创建12个工厂类;而抽象工厂模式依据产品族来创建工厂,仅需4个工厂类,极大减少了系统中类的个数。
3.2 运用
抽象工厂的角色:
-
AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
-
ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
-
AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
-
ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
假设一家软件公司准备推出一款新的手机游戏软件,该软件能够支持IOS、Android和Windows Mobile等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台,为了满足上述需求,试采用抽象工厂模式对其进行设计。
根据需求我们知道,当该游戏在不同的操作系统时,需要分别使用不同的操作控制器和界面控制器,所以我们针对不同操作系统设计一个抽象工厂,该抽象工厂中定义两个方法,分别生产操作控制器和界面控制器。然后生产不同系统的工厂类,在工厂类中生成对应的操作控制器和界面控制器。
操作控制器代码:
界面控制器代码:
抽象工厂代码:
test:
3.3 总结
抽象工厂模式是对工厂方法模式的进一步升级使用,使得工厂方式更符合实际开发需求,在实际开发中往往需要一个产品族来完成工作。抽象工厂模式在新增产品族时很方便,无需修改已有系统,符合“开闭原则”。但抽象工厂模式最大的缺点是对于新增产品很麻烦,需要对原有系统进行较大的修改,不符合“开闭原则”。所以在实际开发中,我们需要衡量具体的需求,选择对应的设计模式,对于需要客户端使用同一产品族的需求时,可以选择抽象工厂模式进行设计。
全部工厂模式
适用场景
-
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
优点
-
屏蔽产品的具体实现,调用者只关心产品的接口。
-
扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
缺点
-
工厂类剧增,增加了系统的复杂度。