PHP面对对象设计模式之工厂模式
当我要实例化类的时候,不直接new这个类,而是通过调用另一个类的一个方法来实例化。这就是工厂模式的核心原理。
工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。
使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。
根据抽象程度的不同,PHP工厂模式分为三种:
简单工厂模式
工厂方法模式
抽象工厂模式
工厂模式的原理:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
工厂方法和简单工厂相对,工厂方法增加了许多代码但是实现的功能和简单工厂一样。但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则。
抽象工厂由多条产品线,而工厂方法只有一条产品线,是抽象工厂的简化。
抽象工厂模式只负责抽象工厂接口,具体工厂交给客户去扩展。在分工时,核心工程师负责抽象工厂和抽象产品的定义,业务工程师负责具体工厂和具体产品的实现。
工厂模式的例子
< ?php
//抽象产品
interface Person {
public function getName();
}
//具体产品实现
class Teacher implements Person {
public function getName() {
return "谷歌老师
";
}
}
class Student implements Person {
public function getName() {
return "明凯学生
";
}
}
//简单工厂
class SimpleFactory {
public static function getPerson($type) {
$person = null;
if ($type == 'teacher') {
$person = new Teacher();
} elseif ($type == 'student') {
$person = new Student();
}
return $person;
}
}
//简单工厂调用
class SimpleClient {
public static function main() {
// 如果不用工厂模式,则需要提前指定具体类
// $person = new Teacher();
// echo $person->getName();
// $person = new Student();
// echo $person->getName();
// 用工厂模式,则不需要知道对象由什么类产生,交给工厂去决定
$person = SimpleFactory::getPerson('teacher');
echo $person->getName();
$person = SimpleFactory::getPerson('student');
echo $person->getName();
}
}
//工厂方法
interface CommFactory {
public function getPerson();
}
//具体工厂实现
class StudentFactory implements CommFactory {
public function getPerson(){
return new Student();
}
}
class TeacherFactory implements CommFactory {
public function getPerson() {
return new Teacher();
}
}
//工厂方法调用
class CommClient {
public static function main() {
$factory = new TeacherFactory();
echo $factory->getPerson()->getName();
$factory = new StudentFactory();
echo $factory->getPerson()->getName();
}
}
//抽象工厂模式另一条产品线
interface Grade {
function getYear();
}
//另一条产品线的具体产品
class Grade1 implements Grade {
public function getYear() {
return '2016级';
}
}
class Grade2 implements Grade {
public function getYear() {
return '2017级';
}
}
//抽象工厂
interface AbstractFactory {
function getPerson();
function getGrade();
}
//具体工厂可以产生每个产品线的产品
class Grade1TeacherFactory implements AbstractFactory {
public function getPerson() {
return new Teacher();
}
public function getGrade() {
return new Grade1();
}
}
class Grade1StudentFactory implements AbstractFactory {
public function getPerson() {
return new Student();
}
public function getGrade() {
return new Grade1();
}
}
class Grade2TeacherFactory implements AbstractFactory {
public function getPerson() {
return new Teacher();
}
public function getGrade() {
return new Grade2();
}
}
//抽象工厂调用
class FactoryClient {
public function printInfo($factory) {
echo $factory->getGrade()->getYear().$factory->getPerson()->getName();
}
public static function main() {
$client = new FactoryClient();
$factory = new Grade1TeacherFactory();
$client->printInfo($factory);
$factory = new Grade1StudentFactory();
$client->printInfo($factory);
$factory = new Grade2TeacherFactory();
$client->printInfo($factory);
}
}
//简单工厂
SimpleClient::main();
//工厂方法
CommClient::main();
//抽象工厂
FactoryClient::main();
//
输出:
谷歌老师
明凯学生
谷歌老师
明凯学生
2016级谷歌老师
2016级明凯学生
2017级谷歌老师
工厂模式的用处:
简单工厂模式: 用来生产同一等级结构中的任意产品。(不能增加新的产品)
工厂类负责创建的对象较少,操作时只需知道传入工厂类的参数即可,对于如何创建对象过程不用关心。
工厂方法模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
当一个类不知道它所必须创建对象的类时,希望由子类来指定它所创建的对象。
抽象工厂模式 :用来生产不同产品种类的全部产品。(不能增加新的产品,支持增加产品种类)
系统不依赖于产品类实例如何被创建,组合和表达的细节,系统的产品有多于一个的产品族,而系统只消费其中某一族的产品,同属于同一个产品族是在一起使用的,所有产品以同样的接口出现,从而使客户端不依赖于实现。
PHP面对对象设计模式之单例模式 PHP面对对象设计模式之注册模式
不错; 应用场景也有