工厂方法模式
1. 回顾简单工厂模式
在简单工厂模式中是把所有的产品集中到一个工厂类中创建完成,而使用者只需要关心传入工厂类的产品标识,即可创建不同的产品;并且简单工厂中提出了三角色,分别是:抽象产品角色(抽象类:abstract class,接口:interfac)是所有具体产品角色的基类、具体产品角色是创建目标、工厂角色是根据使用者传入的产品标识创建所需的产品对象实例。
简单工厂模式的弊端就是随着产品的增加,而工厂类的判断逻辑也相对越来越复杂,及其不利于扩展和维护。如何解决这个问题的哪?
2. 啥时候使用工厂方法模式
你工厂的效益越来越好,产品不断增加,生产效率不能提升,厂长很苦恼;厂长灵机一动,咱也小有资产了,咱为嘛不再搞个厂子嘛(厂长的野心比较大);于是他又搞了个专门生产苹果手机的厂子,并把原厂改为生产小米手机的厂子,这样每个厂子都负责一块生产效率上去了。
3. 工厂方法模式定义
工厂方法模式(Factory Mthod Pattern)又称为工厂模式或多态工厂模式(Polymorphic Factory),它属于类创建型模式。是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
分析:工厂方法模式提供了一个基类工厂,而基类工厂只负责生产产品的公共接口方法,具体产品的生产由具体工厂负责生产,而所有具体产品都有一个抽象产品基类。
举个例子:工厂基类就相当于一个集团,集团下辖很多的生产工厂,但是每个生产工厂只能生产一种类型的产品;
4. 该模式中包含的角色及其职责
1)、Factory:抽象工厂角色
是工厂方法模式的核心,与应用程序无关。任何在模式中创建对象的工厂必须实现这个接口。
2)、ConcreteFactory:具体工厂角色
这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
3)、Product:抽象产品角色
工厂方法模式所创建对象的基类,也就是产品对象的共同父类或共同拥有的接口。
)4、ConcreteProduct:具体产品角色
这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
不废话了,看下面代码!
5. 撸代码
PHP代码哦
/** * 抽象产品角色:IProduct * */
interface IProduct
{
/** * 抽象产品角色提供的 公共接口 创建手机 */
public function createMobilePhone();
}
/** * 具体产品角色:ConcreteIPhoneProduct 生产苹果手机 * */
class ConcreteIPhoneProduct implements IProduct
{
/** * 抽象产品角色提供的 公共接口 创建苹果手机 */
public function createMobilePhone(){
//具体实现代码
}
}
/** * 具体产品角色:ConcreteXiaomiProduct 生产小米手机 * */
class ConcreteXiaomiProduct implements IProduct
{
/** * 抽象产品角色提供的 公共接口 创建小米手机 */
public function createMobilePhone(){
//具体实现代码
}
}
/** * 抽象工厂方法角色:IFactory * */
interface IFactory
{
/** * 抽象工厂方法角色提供 公共接口方法 创建手机 */
public function createMobilePhone();
}
/** * 具体工厂角色:ConcreteXiaomiFactory 生产小米手机 * */
class ConcreteXiaomiFactory implements IFactory
{
/** * 抽象工厂方法角色提供 公共接口方法 创建小米手机 * @return IProduct */
public function createMobilePhone(){
return new ConcreteXiaomiProduct();
}
}
/** * 具体工厂角色:ConcreteIPhoneFactory 生产苹果手机 * */
class ConcreteIPhoneFactory implements IFactory
{
/** * 抽象工厂方法角色提供 公共接口方法 创建苹果手机 * @return IProduct */
public function createMobilePhone(){
return new ConcreteIPhoneProduct();
}
}
/** * 测试工厂方法模式 * */
class TestFactoryMethod
{
//测试方法
public function Test(){
//创建苹果手机
$iphone = (new ConcreteIPhoneFactory())->createMobilePhone();
//创建小米手机
$xiaomi = (new ConcreteXiaomiFactory())->createMobilePhone();
}
}
6. 工厂方法模式的优点
工厂方法用来创建使用者所需要的产品实例,工厂方法向使用者隐藏了对具体产品类的实例化细节,用户者之需要关心所需要的产品对应的具体工厂即可。
系统中新增产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改具体工厂和具体产品,而只需添加一个具体的工厂和具体产品即可。
7. 工厂方法模式的缺点
添加新产品时,需要编写新的具体产品类,而且还需要提供与之对应的具体工厂类,这样系统中类的个数将成对增加,在一定的程度上增加了系统的复杂度。
8. 使用场景
对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品。
只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用那个具体工厂的决定权在使用者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程对于使用者来说是透明的。
9. 总结
工厂方法模式又称为工厂模式,它属于创建型模式。是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式有四种角色,抽象工厂角色、具体工厂角色、抽象产品角色和具体产品角色组成。
工厂方法模式的具体工厂类必须有一个基类,同时具体工厂类创建的具体产品必须出自同一个基类(抽象产品角色)
新增产品类时,只需要添加具体产品类和具体工厂方法类,是成对出现的。