模式介绍
工厂模式:定义一个创建对象的接口,但是让子类去实例化具体类。工厂方法模式让类的实例化延迟到子类中。针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例,在同一等级结构中,支持增加任意产品。
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
什么时候使用工厂方法模式
如果实例化对象的子类可能改变,就要使用工厂方法模式。
工厂方法角色
工厂方法模式包含如下角色:
抽象产品(Product)角色:具体产品对象共有的父类或接口
具体产品(Concrete Product)角色:实现抽象产品角色所定义的接口,并且工厂方法模式所创建的每一个对象都是某具体产品对象的实例
抽象工厂(Creator)角色:模式中任何创建对象的工厂类都要实现这个接口,它声明了工厂方法,该方法返回一个Product类型的对象。
实例
//创建抽象工厂角色
interface Creator {
public function factoryMethod(); # 定义一个工厂方法
}
//定义一个抽象产品角色
interface Product {
public function operation();
}
//创建具体的工厂角色A,并继承抽象工厂角色(Creator )
class ConcreteCreatorA implements Creator {
/**
* 实现工厂方法factoryMethod 返回具体产品ConcreteProductA
* @return ConcreteProductA
*/
public function factoryMethod() {//ConcreteCreatorA 类实例化ConcreteProductA具体类,即创建具体产品实例的工作延迟到其工厂子类去完成
return new ConcreteProductA();
}
}
//创建具体的工厂角色B,并继承抽象工厂角色(Creator )
class ConcreteCreatorB implements Creator {
/**
* 实现工厂方法factoryMethod 返回具体产品ConcreteProductB
* @return ConcreteProductB
*/
public function factoryMethod() {//ConcreteCreatorB 类实例化ConcreteProductB具体类
return new ConcreteProductB();
}
}
//具体的产品角色A
class ConcreteProductA implements Product {
/**
* 接口方法实现 输出特定字符串
*/
public function operation() {
echo 'ConcreteProductA'."\n";
}
}
//具体的产品角色B
class ConcreteProductB implements Product {
/**
* 接口方法实现 输出特定字符串
*/
public function operation() {
echo 'ConcreteProductB '."\n";
}
}
//定义一个静态方法去调用它
class Client {
/**
* Main program.
*/
public static function main() {
$creatorA = new ConcreteCreatorA();
$productA = $creatorA->factoryMethod();
$productA->operation();
$creatorB = new ConcreteCreatorB();
$productB = $creatorB->factoryMethod();
$productB->operation();
}
}
Client::main();
工厂方法模式特点
工厂方法模式的优点:
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
工厂方法模式的缺点:
客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类
来源:CSDN
作者:supreme H
链接:https://blog.csdn.net/qq_42683219/article/details/104135173