小菜学习设计模式(三)—工厂方法(Factory Method)模式

前言

  上一篇《小菜学习设计模式(二)—单例(Singleton)模式》;

  其实大家都知道,在工厂方法(Factory Method)模式之前有个简单工厂模式,也就是静态工厂方法(Static Factory Method)模式,在简单工厂模式之前有个我们都熟悉的三层架构模式,那我们就上到下一层一层的来了解下。

三层架构

  三层架构我们都熟悉,一开始编程的时候也是用的最多,分为:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL),实现了“高内聚,低耦合”的思想。

  关于三层架构不需要说太多,我当时学习的时候,无意间看到李天平老师关于三层的趣味理解,觉得还蛮有意思的,很适合初学者理解,和大家分享下:

小菜学习设计模式(三)—工厂方法(Factory Method)模式

  • 数据库好比猪圈,所有的猪有序地按区域或编号,存放在不同的猪栏里。
  • DAL好比是屠宰场,把猪从猪圈取出来进行(处理)*,按要求取出相应的部位(字段),或者进行归类整理(统计),形成整箱的猪肉(数据集),传送给食品加工厂(BLL)。本来这里都是同一伙人既管抓猪,又管杀猪的,后来觉得效率太低了,就让一部分人出来专管抓猪了(DBUtility),根据要求来抓取指定的猪。
  • BLL好比食品加工厂,将猪肉深加工成各种可以食用的食品(业务处理)。
  • Web好比商场,将食品包装成漂亮的可以销售的产品,展现给顾客(UI表现层)。
  • 猪肉好比Model,无论是哪个厂(层),各个环节传递的本质都是猪肉,猪肉贯穿整个过程。
  • 通用类库Common相当于工人使用的各种工具,为各个厂(层)提供诸如杀猪刀、绳子、剪刀、包装箱、工具车等共用的常用工具(类)。其实,每个部门本来是可以自己制作自己的工 具的,但是那样会使效率比较低,而且也不专业,并且很多工作都会是重复的。因此,就专门有人开了这样的工厂来制作这些工具,提供给各个工厂,有了这样的分工,工厂就可以专心做自己的事情了。

  通过上面的趣味理解,脑海中应该对三层有个了解了。说到这,其实如果大家学习过MVC(模型Model-视图View-控制器Controller)的话,就发现和三层架构有点相似,都有一个表现层,但是其他两层就不同了,三层架构中没有Controller这个概念,MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。当然了。在三层中也提到了Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是以实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。

简单工厂模式

  静态工厂方法(Static Factory Method)模式其实不属于GOF所提出的设计模式中,我们一般在应用的时候结合三层模式下使用工厂模式使用多点,例如下面的解决方案:

小菜学习设计模式(三)—工厂方法(Factory Method)模式

  上面的SeManage.IDAL就相当于抽象产品,SeManage.SQLServerDAL相当于具体产品,SeManage.DALFactory相当于工厂,决定生成何种商品的工厂。

小菜学习设计模式(三)—工厂方法(Factory Method)模式
 1     /// <summary>
 2     /// dal工厂
 3     /// </summary>
 4     public sealed class DataAccess
 5     {
 6         private static readonly string SQLServicePath = ConfigurationManager.AppSettings["SQLServerDAL"];
 7         public DataAccess()
 8         { }
 9 
10         /// <summary>
11         /// 创建Changdi数据层接口。
12         /// </summary>
13         public static SeManage.IDAL.IChangdi CreateChangdi()
14         {
15             string className = SQLServicePath + ".Changdi";
16             return (SeManage.IDAL.IChangdi)Assembly.Load(SQLServicePath).CreateInstance(className);
17         }
18     }
小菜学习设计模式(三)—工厂方法(Factory Method)模式
1     <add key="SQLServerDAL" value="SeManage.SQLServerDAL"/>

  上面的代码表示根据配置文件来创建何种具体抽象类的实例(产品),下面的配置就像工厂机器的开关,决定生产哪种产品。

  通过上面的代码,我们也会发现一些问题,如果产品的种类较多,工厂类里面的生产产品的方法也多,如果出现新的产品,那我们就必须在工厂类里面添加生产新产品的方法,这样就违反了高内聚责任分配原则,使代码变的不容易维护。

工厂方法(Factory Method)模式

  工厂方法(Factory Method)模式是在GOF提出的设计模式中有定义的,如下:为创建对象定义一个接口,让子类决定实例化哪个类,工厂方法让一个类的实例化延迟至子类。

  其实从某种方面可以说,工厂方法模式是简单工厂模式的衍生,也解决了简单工厂模式所出现的问题,例如上面所提到的。工厂方法模式其实就是把工厂抽象化了,我们可以把工厂方法模式拆分成四个元素:抽象工厂(IFactory)、具体工厂(Concrete Factory)、抽象产品(Product)和具体产品(Concrete Product)。根据这四个元素,我们可以简单的画下UML类图:

小菜学习设计模式(三)—工厂方法(Factory Method)模式

  根据上面的UML类图,不难实现其代码:

小菜学习设计模式(三)—工厂方法(Factory Method)模式
 1     /// <summary>
 2     /// 产品接口
 3     /// </summary>
 4     public interface ICar
 5     {
 6         void Travel();
 7     }
 8 
 9     /// <summary>
10     /// 具体产品
11     /// </summary>
12     public class Lexus : ICar
13     {
14         public void Travel()
15         {
16             Console.WriteLine("I‘m a lexus car, I‘m traveling");
17         }
18     }
19 
20     /// <summary>
21     /// 工厂接口
22     /// </summary>
23     public interface ICarFactory
24     {
25         ICar CreateCar();
26     }
27 
28     /// <summary>
29     /// 具体工厂类
30     /// </summary>
31     public class LexusFactory : ICarFactory
32     {
33         public ICar CreateCar()
34         {
35             return new Lexus();
36         }
37     }
38 
39 
40     public class Client
41     {
42         private ICarFactory carFactory;
43         public Client(ICarFactory carFactory)
44         {
45             this.carFactory = carFactory;
46         }
47 
48         public void doSomething()
49         {
50             ICar car = carFactory.CreateCar();
51             car.Travel();
52             //to do something
53         }
54     }
小菜学习设计模式(三)—工厂方法(Factory Method)模式

  调用示例代码:

1         static void Main(string[] args)
2         {
3             Client client = new Client(new LexusFactory());
4             client.doSomething();
5         }

  从上面的代码我们可以看出,工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范, 具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。其实单从这一点上,我们就会发现,和我们之前说的《小菜学习设计模式(一)—模板方法(Template)模式》中提到的模板方法模式的思想有些共同的地方,其实工厂方法(Factory Method)模式是最典型的模板方法(Template Method)模式的应用。

  示例代码下载:FactoryMethod.rar

后记

  插一句:上面的UML是用Edraw Mind Map这一款绘图软件画的,感觉还不错,可以画大部分的图,还在熟悉中,绿色版的哦。

小菜学习设计模式(三)—工厂方法(Factory Method)模式

  下载地址:Edraw Mind Map.rar

  骚年们,和小菜一起整理学习吧,未完待续。。。

小菜学习设计模式(三)—工厂方法(Factory Method)模式

上一篇:入门抠图指南:PS钢笔工具快速抠图教程


下一篇:MAYA动力学重力实例初级教程