一、why use it
简单说一下简单工厂模式:
Class DatabaseFactory
{
function getDB (var command) {
switch command
case 'mysql':
return new Mysql();
case 'oracle':
return new Oracle();
// ...
}
}
// ------------------------------
// 业务代码
var client = DatabaseFactory.getDB('mysql');
print client.select('select * from `table` ...');// 底层已经从mysql换成oracle
这种设计模式下,当业务有变动,比如数据库从mysql,换成oracle。
我们只需要
1、在工厂类里加一个case
2、在业务代码getDB的时候换成'oracle'就可以了
即可实现业务改动。
那么,它有什么缺点?
新增case,把oracle初始化、注入依赖的代码,写在工厂类里,导致代码臃肿,这个工厂类的功能也不够单一。
从设计思想上,新增功能,应该只加代码,尽可能不改动原有代码。
那么就有了抽象工厂的出现。
二、How to use
当然,上面的例子中,为了从mysql换成oracle,接口能对得上,不用改业务代码,它们都应该实现同一套接口或者说是继承一个抽象类。
Abstract Class Database
{
function connect(var host,var port,...) {}
function select (var sql) {}
function update(var sql) {}
// ...
}
// mysql
Class Mysql extends Database
{
// 具体不同的实现
}
而抽象工厂模式,简而言之,就是连这个工厂,也是抽象的。
Abstract Class DatabaseFactory
{
function getDB () {}
}
// mysql
Class MysqlFactory extends DatabaseFactory
{
// 实现这个方法
function getDB () {
var msyql = new Mysql();
// 初始化
mysql.host = '192.168.0.2';
// ...
return mysql;
}
}
// ------------------------------------------
// 业务代码
DatabaseFactory f = new MysqlFactory();
Database db = f.getDB();
db.select(...);
那么,如果我们需求要换成oracle,只需要
1、写个工厂类继承抽象工厂类
2、new的时候,改成OracleFactory
甚至可以不改动业务代码,可以把这个写在配置文件,通过配置文件来new不同的工厂类。这样一来,几乎不用改动原有代码。不用改动原有代码,意味着。。。不用加班 (〃´皿`)q !
网友评论