原文地址:PHP设计模式(八):工厂模式php
在PHP设计模式(七):设计模式分类中咱们提到过建立设计模式(Creation patterns),建立设计模式专一于设计对象(Object)和实例(Instance)的建立过程。
建立设计模式包括下面五种设计模式:程序员
抽象工厂设计模式(Abstract Factory)设计模式
生成器模式(Builder)架构
工厂设计模式(Factory Method)函数
原型设计模式(Prototype Method)ui
单例设计模式(Singleton)this
当程序逐渐扩展的时候,须要更多的新对象,新对象的建立不该该依赖于建立者,换句话说,新对象的建立过程,不该该依赖调用建立函数的对象。为了减小冗余,增长拓展性,工厂模式就是一种建立新对象时使用的设计模式。设计
工厂模式,也是五种设计模式中惟一的类的设计模式(Class patterns),即在类中就能实现的设计模式。
听起来挺抽象?对比原型设计模式,这是一种对象设计模式(Object patterns),经过对象的__clone()方法来实现的设计模式。
在工厂模式中,新建立的对象/产品并不依赖于生产它的对象/工厂,新对象和调用者之间是低耦合状态。一般调用者和工厂交互,由工厂来生成新对象,新对象只和工厂有关。code
简单来讲,当需求对类的个数不明确的时候,可使用工厂模式,如:
你须要建立一个在线博物馆,但你并不确切的知道究竟有多少文物,你不可能无限的增长新的文物类,同时对于损毁的文物,你不可能无限的去清理这些类。
反过来讲,若是你确切的知道类的总量,那么你就没有必要使用工程模式,直接经过继承的方式就能实现好的设计。对象
仍是使用咱们惯用的鲸鱼和鲤鱼的例子,如今咱们想实现一个海洋馆,目前咱们并不肯定究竟有多少海洋生物。
先是一个抽象的工厂类:
<?php abstract class Factory { protected abstract function create(); public function factoryStart() { return $this->create(); } } ?>
而后是两个工厂:鲸鱼工厂和鲤鱼工厂
<?php class WhaleFactory extends Factory { protected function create() { $whale = new Whale(); return $whale->create(); } } class CarpFactory extends Factory { protected function create() { $carp = new Carp(); return $carp->create(); } } ?>
而后是抽象的动物接口:
<?php interface Animal { public function create(); } ?>
而后是具体的动物类:鲸鱼类和鲤鱼类
<?php class Whale implements Animal { private $name; public function create() { $this->name = "Whale"; return $this->name . " is created.\n"; } } class Carp implements Animal { private $name; public function create() { $this->name = "Carp"; return $this->name . " is created.\n"; } } ?>
下面给出使用工厂建立鲸鱼和鲤鱼的代码:
<?php $whaleFactory = new WhaleFactory(); echo $whaleFactory->factoryStart(); $carpFactory = new CarpFactory(); echo $carpFactory->factoryStart(); ?>
运行一下:
Whale is created. Carp is created.
到这里你是否是以为,其实直接生成两个类就好了,何须搞这么复杂?别着急,好戏在后面。
因为Interface的限制,修改类的方法被限定在了create()方法中,所以能够避免偷懒的程序员新增长的不合理函数。
简单修改一下:
<?php class Whale implements Animal { private $name; public function create() { $this->name = "Whale"; return $this->name . " is created. Whale eats fish.\n"; } } class Carp implements Animal { private $name; public function create() { $this->name = "Carp"; return $this->name . " is created. Carp eats moss.\n"; } } ?>
因为对象是由工厂造出来的,外部不可能直接调用或者修改类的实现,类的修改被限定在了类的对外接口上。这样的架构易于扩展。
工厂模式的灵活,在于能够只拥有一个工厂,却能生产多个类/产品。
修改咱们的抽象工厂,给create()方法增长animal接口:
<?php abstract class Factory { protected abstract function create(Animal $animal); public function factoryStart($animal) { return $this->create($animal); } } ?>
而后合并以前的鲸鱼工厂和鲤鱼工厂:
<?php class AnimalFactory extends Factory { protected function create(Animal $animal) { return $animal->create(); } } ?>
修改使用工厂建立鲸鱼和鲤鱼的代码:
<?php $animalFactory = new AnimalFactory(); echo $animalFactory->factoryStart(new Whale()); echo $animalFactory->factoryStart(new Carp()); ?>
运行一下:
Whale is created. Whale eats fish. Carp is created. Carp eats moss.
鲸鱼类和鲤鱼类源源不断的从一个工厂中被建立出来了。经过这种设计模式,类的建立过程统一经过一个接口来实现,接口外部并不须要关心类是如何被建立出来的,而接口内部实现也获得了很好的拓展性。
本文介绍了工厂设计模式,使用这种设计模式,可让你经过一个或多个工厂的接口,建立无数新类,调用任意类的方法。因为接口严格定义了新类/产品的形态,所以在维护和拓展的时候,能够省去很多力气。