程序员

设计模式/抽象工厂:通通都来抽象吧

2018-09-08  本文已影响42人  Allan_野草

一、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 !

上一篇 下一篇

猜你喜欢

热点阅读