美文网首页程序员
设计模式/抽象工厂:通通都来抽象吧

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

作者: Allan_野草 | 来源:发表于2018-09-08 17:45 被阅读42次

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

    相关文章

      网友评论

        本文标题:设计模式/抽象工厂:通通都来抽象吧

        本文链接:https://www.haomeiwen.com/subject/xaclgftx.html