共计 2894 个字符,预计需要花费 8 分钟才能阅读完成。
这篇文章将为大家详细讲解有关 php 设计模式中工厂模式有什么用,丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
使用工厂模式的目的或目标?
工厂模式的最大优点在于创建对象上面,就是把创建对象的过程封装起来,这样随时可以产生一个新的对象。
减少代码进行复制粘帖,耦合关系重,牵一发动其他部分代码。
通俗的说,以前创建一个对象要使用 new,现在把这个过程封装起来了。
假设不使用工厂模式:那么很多地方调用类 a,代码就会这样子创建一个实例:new a(), 假设某天需要把 a 类的名称修改,意味着很多调用的代码都要修改。
工厂模式的优点就在创建对象上。
工厂模式的优点就在创建对象上。建立一个工厂(一个函数或一个类方法)来制造新的对象, 它的任务就是把对象的创建过程都封装起来,
创建对象不是使用 new 的形式了。而是定义一个方法,用于创建对象实例。
每个类可能会需要连接数据库。那么就将连接数据库封装在一个类中。以后在其他类中通过类名:
为什么引入抽象的概念?
想一想,在现实生活中,当我们无法确定某个具体的东西的时候,往往把一类东西归于抽象类别。
工厂方法:
比如你的工厂叫做“香烟工厂”,那么可以有“七匹狼工厂”“中华工厂”等,但是,这个工厂只生厂一种商品:香烟;
抽象工厂:无法描述它到底生产什么产品,它生产很多类型的产品 (所以抽象工厂就会生成子工厂)。
你的工厂是综合型的,是生产“一系列”产品,而不是“一个”,比如:生产“香烟”,还有“啤酒”等。然后它也可以有派生出来的具体的工厂,但这些工厂都是生产这一系列产品,只是可能因为地域不一样,为了适应当地人口味,味道也不太一样。
工厂模式:理解成只生成一种产品的工厂。比如生产香烟的。
工厂方法:工厂的一种产品生产线。比如键盘的生成过程。
别人会反驳:吃饱了没事干,一定要修改类名称呢?这个说不定。一般都不会去修改类名称。
其实工厂模式有很多变体,抓住精髓才是关键:只要是可以根据不同的参数生成不同的类实例,那么就符合工厂模式的设计思想。
这样子让我联想到框架中经常会有负责生成具体类实例的方法供调用。
由于前面使用过 phpcms, 用 phpcms 的来帮助理解,更加好,如下:
pc_base:load_app_class(order // 参数名称就是类名称。将会生成得到 order 这个实例。传递不同的参数得到不同的类实例,这个就符合工厂模式。
pc_base:load_app_class(comment // 生成一个 comment 类实例
// 当然 load_app_class 这个方法里面还会结合了单件模式的思想。避免调用 n 次,就重复创建 n 个相同的实例
工厂模式我想到的一个典型的应用就是:php 可能要链接 mysql,也可能要链接 sqlserver,还有其他什么数据库。那么做一个抽象的数据库类,
这个类就是一个工厂类,专门负责产生不同的对象。
这样子做很方便扩展。我们在直接链接数据库的时候,不是使用代码 new Mysql($host,$username,$password,$dbname)的形式
而可以动态生成一个连接数据库的实例。可以是 mysql,也可以是连接 oracle 的。
class DbFactory
{
function static factory($db_class_name)
{
$db_class_name = strtolower($db_class_name);
if (include_once Drivers/ . $db_class_name . .php) {
$classname = Driver_ . $db_class_name;
return new $db_class_name;
} else {
throw new Exception (对应的数据库类没找到
}
}
}
DbFactory::factory(mysql
DbFactory::factory(oracle
在 thinkphp 框架中也有对应的实现:
Db.class.php 就是一个工厂类(也可以叫做数据库中间层,之所以叫做中间层,是因为可以操作 mysql、oracle 等各数据库。而这个类就是中间层作用, 屏蔽掉具体的实现。让程序员可以不改动原来的查询代码。中间层来对接 mysql、oracle 等数据库。
Db.class.php 中有个 factory()方法来创建不同的数据库实例
public function factory($db_config=) {
// 读取数据库配置
$db_config = $this- parseConfig($db_config);
if(empty($db_config[ dbms]))
throw_exception(L( _NO_DB_CONFIG_
// 数据库类型
$this- dbType = ucwords(strtolower($db_config[ dbms]));
$class = Db . $this- dbType;
if(is_file(CORE_PATH. Driver/Db/ .$class. .class.php)) {
// 内置驱动
$path = CORE_PATH;
}else{// 扩展驱动
$path = EXTEND_PATH;
}
// 检查驱动类
if(require_cache($path. Driver/Db/ .$class. .class.php)) {
$db = new $class($db_config);
// 获取当前的数据库类型
if(pdo != strtolower($db_config[ dbms]) )
$db- dbType = strtoupper($this- dbType);
else
$db- dbType = $this- _getDsnType($db_config[ dsn
if(APP_DEBUG) $db- debug = true;
}else {
// 类没有定义
throw_exception(L( _NOT_SUPPORT_DB_). : . $db_config[dbms
}
return $db;
}
还有做支付接口的时候,未来可能对应不同的支付网关:支付宝、财付通、网银在线等。方便未来扩展, 设计成工厂模式。定一个专门生产网关接口的工厂,抽象出来, 做成接口形式,让所有的子类都要实现它的接口。以后加一个支付方式,要使用哪一种支付方式,改变一下参数即可。
书籍 php 权威编程 (英文名称为 PHP 5 Power Programming)也提到一个工厂模式的例子,学到一招:在为用户注册的时候,分为很多种角色的用户。比如册用户,匿名用户、管理员用户等。完全使用可以使用工厂的思想来实现, 代码也容易维护, 为每种角色可以生成操作的类。
定义以下几个类:
UserFactory 用户工厂类,负责生成不同的用户类
User:用户类的基类,所有用户类都是继承这个类
不同角色的类:注册用户类、匿名用户类、管理员用户类
关于“php 设计模式中工厂模式有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。