php设计模式之工厂方法
最近在学习设计模式,很多地方还理解的不够。在这里记录一下自己学习的东西,方便自己以后查看,同时也给正在学这部分的同学提供一点参考。
工厂方法是属于创建型的设计模式,同属于创建型的设计模式还有--生成器、抽象工厂、原型和单例。
一、什么是工厂方法模式?
工厂方法模式就是创建“某种东西”。对于工厂方法模式,要创建的“东西”是一个产品,这个产品与创建它的类之间不存在绑定。实际上,为了保持这种松散的耦合,客户会通过一个工厂发出请求。再由工厂创建所请求的产品。也可以换一种方式考虑,利用工厂方法模式,请求者只发出请求,而不具体创建产品。
二、实现工厂方法
工厂方法模式一共要实现两个接口,一个是创建工厂的Creator接口,一个是创建产品的Product接口。下面展示一下建立工厂的接口,Creator.php
1 <?php 2 //建立工厂 3 abstract class Creator 4 { 5 6 protected abstract function factoryMethod(); 7 8 public function startFactory() 9 { 10 $mfg = $this->factoryMethod(); 11 return $mfg; 12 } 13 }
这里面一共定义了两个方法,一个是抽象的factoryMethod,这个要求其子类强制实现这个方法,另外一个startFactory,一个对外的普通方法接口,客户端可以直接请求这个方法,就可以执行工厂方法了。
下面我们分别实现两个工厂,一个是FruitsFactory.php,一个是PenFactory.php。你可以理解为一个是生产水果的工厂,一个生产笔的工厂。FruitsFactory.php代码实现如下:
1 <?php 2 //水果工厂 3 include_once('Creator.php'); 4 include_once('Apple.php'); 5 6 class FruitsFactory extends Creator 7 { 8 9 protected function factoryMethod() 10 { 11 $obj = new Apple(); 12 return $obj->getProperties(); 13 } 14 }
PenFactory.php的代码如下:
1 <?php 2 //生产笔工厂 3 include_once('Creator.php'); 4 include_once('Pencil.php'); 5 6 class PenFactory extends Creator 7 { 8 protected function factoryMethod() 9 { 10 $obj = new Pencil(); 11 return $obj->getProperties(); 12 } 13 }
两个工厂的代码基本上相同,只是生产的产品不同,实现了不同的产品类而已。当用户向水果工厂发出请求时,水果工厂去调用苹果的生产方法Apple.php去实现苹果的生产。工厂方法模式中生产是由Product接口去实现的,这样的同时就把工厂和产品
生产之间进行了解偶。当苹果产品的工艺发生改变的时候,我们不需要去修改水果工厂的方法,而只需要修改Apple.php这个文件,就可以在工厂接口不变的情况下,改变Apple的生产工艺。
Product.php接口,这里需求很简单,只要一个生产的方法就行了。
1 <?php 2 //产品接口 3 interface Product 4 { 5 public function getProperties(); 6 }
Apple.php苹果生产的方法:
1 <?php 2 //苹果产品 3 include_once('Product.php'); 4 5 class Apple implements Product 6 { 7 8 public function getProperties() 9 { 10 return "making Apple"; 11 } 12 }
Pencil.php笔生产的方法:
1 <?php 2 //铅笔产品 3 include_once('Product.php'); 4 5 class Pencil implements Product 6 { 7 8 public function getProperties() 9 { 10 return "making Pencil"; 11 } 12 }
下面就展示一下,客户端的请求,Client.php
1 <?php 2 //客户端 3 include_once('FruitsFactory.php'); 4 include_once('PenFactory.php'); 5 6 class Client 7 { 8 9 public function __construct() 10 { 11 $fobj = new FruitsFactory(); 12 echo $fobj->startFactory() . "<br/>"; 13 $pobj = new PenFactory(); 14 echo $pobj->startFactory() . "<br/>"; 15 } 16 } 17 18 new Client();
由此可见,用户想要不同的产品。只需要去不同的工厂去发出请求,这时工厂会根据自己生产的产品,返回用户所需的产品。运行结果:
总结一下:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
工厂方法模式应用场景:
1.类不知道自己要创建哪一个对象
2.类用它的子类来指定创建哪个对象
3.客户需要清楚创建了哪一个对象