最近在面试时,面试官总会多少提及写设计模式的话题,设计模式其实在我们的程序中时常被用到,只是自己不去想这是那种设计模式。打算以后好好学习下设计模式希望能够深入理解这些先人总结下来的宝贵经验。
简单工厂模式
我们在编程的时候总会遇到这样的问题,当我们实例化一个类产生一个对象时,这个对象只能依赖于这个类了。当这个类需要变化时或者需要增加新的功能时,我们就要将与所有与这个对象有关的操作进行修改。那么我们怎么能让对象来应对 具体实例化类型 的变化呢。
简单工厂模式是 专门定义一个类来负责创建其他类的实例,被创建的实例通常有共同的父类,通常根据参数的不同来返回各自的实例。
简单工厂分为 工厂角色 抽象产品角色 具体产品角色
工厂角色(Creator):是简单工厂的核心,负责实现创建所有实例的内部逻辑。被外部直接调用,创建所需的产品对象。
抽象产品角色(Product ):是简单工厂的所创建的所以对象的父类,负责描述所有产品实例的所共有的公共接口。
具体产品角色(Concrete Product):继承自抽象产品角色,一般为多个,是抽象工厂的具体目标,所以创建的对象都是充当这个角色的某个具体类的实例。
UML (借用)
优缺点:
优点:外界不需要知道怎么创建产品,只需要怎么消费, 不必知道对象是如何创建和组织。外界与具体类隔离开来,耦合性低。
明确区分了各自的职责和权力划分,有利于整个软件体系结构的优化。
缺点:工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则
虽然简单工厂模式能够适应一定的变化,但是它所能解决的问题是远远有限的。它所能创建的类只能是事先教考虑到的,如果需要添加新的类,则就需要改变工厂类了。(这个问题在下一个工厂方法模式将得到很好的解决)
现实生活中例子:
每次参加不同的聚会或者与不同的人见面,可能穿的衣服是不一样的,比如,你今天上午要与你的一个新客户见面,你可能会对你的老婆说:老婆,给拿件商务装(参数),我要去见我的一个客户,你老婆(工厂类)接到你的请求(商务装参数)后,从衣柜中取出一件商务装(具体产品),交给你。整个过程就完成了。
分析:
你可能根据不同的条件,要的衣服是不一样的,但要的衣服都是已经在你的衣柜中存在的。并且,每件上衣它们都属于同一种抽象,即它们可以从一个抽象类或接口中继承,这此衣服各自都有一定特征,这些都是条件。然后你要的时候,就可以向你老婆说一种特征,她就会根据这个特征为你服务了。这就是典型的简单工厂模式的应用。
抽象产品类代码
2 /// 抽象产品类:上衣
3 /// </summary>
4 public interface ICoat
5 {
6 void GetYourCoat();
7 }
非常简单,是吧?这里我只是举一个仅仅能说明问题的例子,在具体的项目中,可能是很复杂的哦。。
具体产品类代码
2{
3 /// <summary>
4 /// 具体产品类:商务上衣
5 /// </summary>
6 public class BusinessCoat:ICoat
7 {
8 public void GetYourCoat()
9 {
10 Console.WriteLine("商务上衣");
11 }
12 }
13
14 /// <summary>
15 /// 具体产品类:时尚上衣
16 /// </summary>
17 public class FashionCoat : ICoat
18 {
19 /// <summary>
20 /// 实现ICoat中定义的方法
21 /// </summary>
22 /// <returns></returns>
23 public void GetYourCoat()
24 {
25 Console.WriteLine("时尚上衣");
26 }
27 }
28}
简单工厂模式中最核心的部分:工厂类
2{
3 /// <summary>
4 /// 简单工厂模式中的核心部分:工厂类
5 /// </summary>
6 public class Factory
7 {
8 public ICoat CreateCoat(string styleName)
9 {
10 switch (styleName.Trim().ToLower())
11 {
12 case "business":
13 return new BusinessCoat();
14 case "fashion":
15 return new FashionCoat();
16 default :
17 throw new Exception("还没有你要的那种衣服");
18 }
19 }
20 }
21}
再看一下客户在调用的时候的代码
2 /// 客户类
3 /// </summary>
4 class Client
5 {
6 static void Main(string[] args)
7 {
8 ICoat food;
9 try
10 {
11 Factory factory = new Factory();
12
13 Console.Write("我要的是时尚上衣\t");
14 food = factory.CreateCoat("fashion");
15 food.GetYourCoat();
16
17 }
18 catch (Exception ex)
19 {
20 Console.WriteLine(ex.Message);
21 }
22 }
23 }