工厂方法模式 - OK

  工厂方法模式(Factory Method),定义了一个用于建立对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到子类。javascript

  工厂方法模式在实现时,客户端须要决定实例化哪个工厂来实现运算类,选择判断的问题还存在,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。想要加功能,原本是修改工厂类的,而如今是修改客户端。html

  下面给出工厂方法模式UML图:java

    

  工厂方法模式示例:git

复制代码
namespace 工厂方法模式
{
    //数据库类
    class DataBase
    {
        public virtual string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //SQLServer类
    class SQLServer : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //Oracle类
    class Oracle : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT * FROM Table WHERE ROWRUM <= 1";
        }
    }

    //总结来讲,下面的1个接口两个类实现的就是简单工厂中switch的功能
    //数据库工厂
    interface IFactory
    {
        DataBase GetDataBase();
    }

    //SQLServer工厂
    class SQLServerFactory : IFactory
    {
        public DataBase GetDataBase() { return new SQLServer(); }
    }

    //Oracle工厂
    class OracleFactory : IFactory
    {
        public DataBase GetDataBase() { return new Oracle(); }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IFactory factory = new SQLServerFactory();   //依赖于具体工厂类,但不依赖具体实现了了
            DataBase DB = factory.GetDataBase();         //从得到的工厂中 获取学雷锋对象
            Console.WriteLine(DB.SelectTopOne());

            //可是我有一种很强烈的感受,既然如此,何不这样,虽然依赖了具体实现类,可是少了3个类
            //DataBase DB = new SQLServer();
            //Console.WriteLine(DB.SelectTopOne());

            Console.ReadKey();
        }
    }
}
复制代码

  类图以下:数据库

  

  为了对比与简单工厂模式的区别,如下再写个简单工厂模式的来比较下:设计模式

复制代码
namespace 简单工厂
{
    public class Program
    {
        static void Main(string[] args)
        {
            DataBase DB = SimpleFactory.GetInstance("Oracle");
            Console.WriteLine(DB.SelectTopOne());

            DataBase DB2 = SimpleFactory.GetInstance("SQLServer");
            Console.WriteLine(DB2.SelectTopOne());

            Console.ReadKey();
        }
    }

    //简单工厂类,判断类,用于返回对应的的对象
    public class SimpleFactory
    {
        public static DataBase GetInstance(string type)
        {
            DataBase db = null;
            switch (type)
            {
                default:
                case "SQLServer":
                    db = new SQLServer();
                    break;
                case "Oracle":
                    db = new Oracle();
                    break;
            }
            return db;
        }
    }

    //基类
    public class DataBase
    { 
        public virtual string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //实现类1
    public class SQLServer : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //实现类2
    public class Oracle : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT * FROM Table WHERE ROWRUM <= 1";
        }
    }
}
复制代码

  比较一下,二者实现的代码相似。ide

  对于简单工厂模式,在客户端方面,去除了对具体雷锋的依赖,便可以不出现具体的雷锋类(如大学生,社区志愿者)。但若是要添加一个学雷锋的中学生,就须要修改工厂类里面的case判断,以及添加一个具体类。post

  对于工厂方法模式,由客户端方面来决定实例化哪个工厂来实现运算类,固然判断的问题仍是存在。相比于简单工厂,判断的工做交到客户端来处理。可是有一个好处,就是当须要添加一个DB2实现时,就没有必要再修改原有的工厂类,只须要添加一个工厂类(这就是为什么这么多工厂类,一个实现类就有一个工厂类),以及具体类(如例子中的SQLServer、Oracle)。this

  客户端new的地方。相对于简单工厂而言,对修改封闭了,符合开放封闭原则。可是带来了代价就是类比较多(工厂类太多了,找死你)。spa

 
 
分类: 设计模式
 
0
0
 
(请您对文章作出评价)
 
« 上一篇: 代理模式 - OK
» 下一篇: 原型模式 - OK
相关文章
相关标签/搜索