C#设计模式--简单工厂模式

简单工厂模式是属于创建型模式,但不属于23种GOF设计模式之一。

举一个例子:一个公司有不同的部门,客户根据需要打电话到不同的部门。客户相当于上端,不同部门相当于下端。不使用简单工厂模式来实现的例子如下:

    #region 上端
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("********不使用工厂方法******");
            HRDept hr = new HRDept();
            hr.Call();
            TechnologyDept technology = new TechnologyDept();
            technology.Call();
            Console.ReadKey();
        }
    }
    #endregion
    #region 下端
    class HRDept
    {
        public void Call()
        {
            Console.WriteLine("这是人事部");
        }             
    }
    class TechnologyDept
    {
        public void Call()
        {
            Console.WriteLine("这是技术部");
        }
    }
    #endregion
View Code

从这个例子可以发现客户需要找一个部门,就必须知道那个部门的电话号码。即上端直接依赖于下端。 每回都需要去new一下,完全把下端类暴露给上端。并且下端改变,上端必须改变。而在我们的实际生活中,客户并不知道每个部门的具体号码,都是打电话到前台,让前台将电话转到对应部门。而前台就相当于一个简单工厂。HRDept类和TechnologyDept类都有Call()方法,所以可以定义一个接口,声明这个方法。

    #region 上端
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("********工厂方法******");
            IDept hr = SimpleFactory.CreateInstance("HR");
            hr.Call();
            IDept technology = SimpleFactory.CreateInstance("Technology");
            technology.Call();
            Console.ReadKey();
        }
    }
    #endregion
    #region 下端
    class SimpleFactory
    {
        public static IDept CreateInstance(string name)
        {
            switch (name)
            {
                case "HR":
                    return new HRDept();
                case "Technology":
                    return new TechnologyDept();
                default:
                    throw new Exception("部门名称错误");
            }
        }
    }
    interface IDept
    {
        void Call();
    }
    class HRDept: IDept
    {
        public void Call()
        {
            Console.WriteLine("这是人事部");
        }             
    }
    class TechnologyDept: IDept
    {
        public void Call()
        {
            Console.WriteLine("这是技术部");
        }
    }
    #endregion
View Code

 由上可以发现简单工厂,创建一个工厂类,负责对象的创建,而不是在上端使用的地方直接创建。面向抽象,屏蔽细节。 缺陷:把对象创建转移到工厂,上端不关心细节,修改类的时候需要修改工厂方法。工厂方法自身高耦合,矛盾转移,将上端与下端的耦合转移到工厂方法,严重违背单一职责。

简单工厂:创建一个工厂类,负责对象的创建,而不是在上端使用的地方直接创建。

缺陷:把对象创建转移到工厂,上端不关心细节,修改类的时候需要修改工厂方法。工厂方法自身高耦合,矛盾转移,将上端与下端的耦合转移到工厂方法,严重违背单一职责。

工厂类完成对象的创建。在使用时只需要调用工厂类的CreateInstance()方法,通过传递不同参数,创建不同的类。

简单工厂的升级

1.简单工厂+配置文件

代码示例:

工厂类

 class SimpleFactory
    {        
        //简单工厂+配置文件
        //添加引用System.Configuration.dll
        private static string RaceTypeConfig = ConfigurationManager.AppSettings["DeptConfig"];
        public static IDept CreateInstanceConfig()
        {
            switch (RaceTypeConfig)
            {
                case "HR":
                    return new HRDept();
                case "Technology":
                    return new TechnologyDept();
                default:
                    throw new Exception("部门名称错误");
            }
        }
     
    }
View Code

 配置文件

<appSettings>
    <add key="DeptConfig" value="HRDept"/>    
  </appSettings>
View Code

 

2.简单工厂+配置文件+反射

代码示例:

工厂类

class SimpleFactory
    {     
        //简单工厂+配置文件+反射
        private static string RaceTypeReflect = ConfigurationManager.AppSettings["DeptReflect"];
        public static IDept CreateInstanceReflect()
        {
            string assemblyName = RaceTypeReflect.Split(',')[0];
            string typeName = RaceTypeReflect.Split(',')[1];
            return (IDept)(Activator.CreateInstance(assemblyName, typeName).Unwrap());
        }
    }
View Code

 配置文件

 <appSettings>
    <add key="DeptReflect" value="SimpleFactory,SimpleFactory.HRDept"/>
  </appSettings>
View Code

 

posted @ 2017-11-03 15:34  人间的四月天  阅读(219)  评论(0编辑  收藏  举报