最新消息:红方科技年末特惠:.com域名55元、云虚机五折优惠,买3年送2年,更有智能建站套餐等你来取!

工厂模式

Linux yinhexi 1952浏览 0评论

【工厂模式的优点和缺点】
工厂模式的优点
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

工厂模式的缺点
客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类

【工厂模式适用场景】
1、当一个类不知道它所必须创建的对象的类的时候
2、当一个类希望由它的子类来指定它所创建的对象的时候
3、当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候

【工厂模式与其它模式】
抽象工厂模式(abstract factory模式):Abstract Factory模式经常使用工厂方法来实现
Template Method模式: 工厂方法通常在Template Methods中被调用

<?php
/**************************************逻辑工厂模式**************************/
/*
【工厂方法模式与简单工厂模式】
工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了”开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
*/
//抽象工厂角色
interface Creator {
public function factoryMethod();
}

//具体工厂角色A
class ConcreteCreatorA implements Creator {
public function factoryMethod() {
return new ConcreteProductA();
}
}

//具体工厂角色B
class ConcreteCreatorB implements Creator {
public function factoryMethod() {
return new ConcreteProductB();
}
}

//具体工厂角色C
class ConcreteCreatorC implements Creator {
public function factoryMethod() {
return new ConcreteProductC();
}
}

//抽象产品角色
interface Product {
public function operation();
}

//具体产品角色A
class ConcreteProductA implements Product {
public function operation() {
echo 'ConcreteProductA<br/>';
}
}

//具体产品角色B
class ConcreteProductB implements Product {
public function operation() {
echo 'ConcreteProductB<br/>';
}
}

//具体产品角色C
class ConcreteProductC implements Product {
public function operation() {
echo 'ConcreteProductC<br/>';
}
}

class Client {
public static function main() {
$creatorA = new ConcreteCreatorA();
$productA = $creatorA->factoryMethod();
$productA->operation();

$creatorB = new ConcreteCreatorB();
$productB = $creatorB->factoryMethod();
$productB->operation();

$creatorC = new ConcreteCreatorC();
$productC = $creatorC->factoryMethod();
$productC->operation();
}
}

Client::main();

/**************************************数据工厂模式**************************/
/*
使用工厂类解决数据库可移值性问题,在数据库应用程序中,工厂模式可以在以下两个方面起作用。

1.使软件更容易支持各种不同的数据库平台,用于扩展用户群

2.如果软件是内部使用,需要修改数据库时,可以容易将应用程序移值到别一个平台

在代码中,创建了一个名为User的数据库表来测试它,这个表定义一个名为email的varchar类型字段

应用程序不必知道它与何种类型的数据库连接,只会基于IDatabaseBindings接口定义的规则直接与工厂返回的实例打交道。
*/
//抽象数据角色
interface IDatabaseBindings {
public function useExists($email);
}

//具体数据角色PGSQL
class PGSQL implements IDatabaseBindings {
protected $_connection;
public function __construct() {
$this->_connection = pg_connect('dbname=example_db');
}
public function userExists($email) {
$emailEscaped = pg_escape_string($email);
$query = "SELECT 1 FROM users WHERE email='".$emailEscaped."'";
if($result=pg_query($query,$this->_connection)) {
return (pg_num_rows($result)>0)?true:false;
} else {
return false;
}
}
}

//具体数据角色MYSQL
class MYSQL implements IDatabaseBindings {
protected $_connection;
public function __construct() {
$this->_connection = mysql_connect('localhost');
mysql_select_db('example_db',$this->_connection);
}
public function userExists($email) {
$emailEscaped = mysql_real_escape_string($email);
$query = "SELECT 1 FROM uses WHERE email='".$emailEscaped."'";
if($result=mysql_query($query,$this->_connection)) {
return (mysql_num_rows($result)>0)?true:false;
} else {
return false;
}
}
}

//工厂角色
class DatabaseFactory {
public static function factory() {
$type = loadtypefromconfigfile();
switch($type) {
case 'PGSQL':
return new PGSQL();
break;
case 'MYSQL':
return new MYSQL();
break;
}
}
}

$db = DatabaseFactory::factory();
$db->userExists('person@example.com');
?>

转载请注明:红方博客 » 工厂模式