zoukankan      html  css  js  c++  java
  • 工厂方法模式

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

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

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

        

      工厂方法模式示例:

    复制代码
    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";
            }
        }
    }
    复制代码

      比较一下,两者实现的代码类似。

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

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

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

     
     
    分类: 设计模式
     
    0
    0
     
    (请您对文章做出评价)
     
    « 上一篇:代理模式 - OK
    » 下一篇:原型模式 - OK
  • 相关阅读:
    CentOS 下搭建Jenkins
    SRVE0255E: 尚未定义要处理 ***的 Web 组/虚拟主机。
    WebSphere Application Server中manageprofiles的使用
    WAS 与IHS集成问题
    CentOS ln 链接
    VIM常见命令
    虚拟机VM下CentOS7部署WASND9+HTTP9
    CentOS7下安装GUI图形界面
    CentOS 系统时间与硬件时间
    hive 排序和聚集
  • 原文地址:https://www.cnblogs.com/mingxuantongxue/p/4778105.html
Copyright © 2011-2022 走看看