-
概念
工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。
-
好处
使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需要更改该工厂方法内容即可,不需要逐一寻找代码中具体实例化的地方(new 处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。
-
分类
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
-
简单工厂模式
简单工厂模式又称静态工厂模式,之所以可以这么说,是因为简单工厂模式是通过一个静态方法来创建对象的
<?php class DbMysql { public function conn() { echo "连接MySQL"; } } class DbSqlite { public function conn() { echo "连接SQLite"; } } class DbFactory { public static function createIns($type) { switch ($type) { case 'mysql': return DbMysql(); break; case 'sqlite': return new DbSqlite(); break; default: throw new ErrorException('类型错误'); } } } $mysql = DbFactory::createIns('mysql'); $mysql->conn(); $sqlite = DbFactory::createIns('sqlite'); $sqlite->conn();
-
工厂方法模式
简单工厂模式实现了产品类的代码跟客户端代码的分离,但会有一个问题,优秀的代码是符合“开闭原则”如果你要加一个C类产品,你就要修改工厂类里面的代码,也就是说要增加条件语句如:switch–case。对于这个问题,接下来的工厂方法模式可以解决这个问题。
-
概念
工厂方法就是为配一个产品提供一个独立的工厂类,通过不同的工厂实例来创建不同的产品实例。
-
优点
- 拥有良好的封装性,代码结构清晰,对于每一个对象的创建都是有条件约束的。如:调用一个具体的产品对象,只需要知道这个产品的类名和约束参数就可以了,不用知道创建对象自身的复杂过程。降低模块之间的耦合度。
- 拥有良好的扩展性,新增一个产品类,只需要适当的增加工厂类或者扩展一个工厂类,如下面的例子中,当需要增加一个数据库Oracle的操作,则只需要增加一个Oracle类,工厂类不用修改任务就可完成系统扩展。
- 屏蔽产品类,这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。
-
使用场景
- 支付宝、微信、银联的连接方式(connectMode),支付方式(payMode)。使用工厂模式,“客户”就不需要知道具体的链接方式和支付方式了,只需要调用connectMode和payMode即可。
- MySQL、SQL Server、Oracle等数据库的连接方式(connectMode)、查询方式(selectMode)等操作可以使用工厂模式进行封装。
<?php //数据库操作接口 interface Db { public function conn(); } class DbMysql implements Db { public function conn() { echo "链接MySQL"; } } class DbSqlite implements Db { public function conn() { echo "连接SQLite"; } } //工厂接口 interface Factory { public static function createIns(); } class MysqlFactory implements Factory { public static function createIns() { return new DbMysql(); } } class SqliteFactory implements Factory { public static function createIns() { return new DbSqlite(); } } //客户端 $mysql = MysqlFactory::createIns(); $mysql->conn(); $sqlite = SqliteFactory::createIns(); $sqlite->conn();
-
-
抽象工厂模式
-
概念
抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象,而且使用抽象工厂模式还要满足以下条件:
- 系统中有多个产品族,而系统一次只可能消费其中一族产品
- 同属于同一产品族的产品可以使用
- 产品族:位于不同产品等级结构中,功能相关联的产品组成的家族。下面例子的汽车和空调就是两个产品树,奔驰C200+格力某型号空调就是一个产品族,同理,奥迪A4+海尔某型号空调也是一个产品族。
<?php //汽车(抽象产品接口) interface AutoProduct { public function dirve(); } class AudiA4Product implements AutoProduct { public function dirve() { echo '奥迪A4'; } } class BenzC200Product implements AutoProduct { public function dirve() { echo '奔驰C200'; } } //空调(抽象产品接口) interface AirCondition { public function blow(); } class GreeAirCondition implements AirCondition { public function blow() { echo '格力'; } } class HaierAirCondition implements AirCondition { public function blow() { echo '海尔'; } } //工厂接口 interface Factory { public static function getAuto(); public static function getAirCondition(); } //工厂A 奥迪A4+海尔空调 class AFactory implements Factory { public static function getAuto() { return new AudiA4Product(); } public static function getAirCondition() { return new HaierAirCondition(); } } //工厂B 奔驰+格力 class BFactory implements Factory { public static function getAuto() { return new BenzC200Product(); } public static function getAirCondition() { return new GreeAirCondition(); } } //客户端 //A工厂制作车 $auto_carA = AFactory::getAuto(); $auto_airA = AFactory::getAirCondition(); //奥迪+空调 $auto_carA->dirve(); $auto_airA->blow();
-
-
三种工厂模式的比较
- 简单工厂:用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
- 工厂方法:用来生产同一等级结构中的固定产品。(支持增加任意产品)
- 抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)