工厂模式

一、背景

  最近在工作中,要修改离职的同事的代码,发现有一个函数代码长度达到了1000行,让我痛不欲生。看过之后发现里面大部分是if...else构成的代码,这应该就是迭代频繁的产物吧。于是为了看着舒服,就着手改造了一下。

二、什么时候采用工厂模式

   使用工厂模式当然不仅仅是为了代码看着舒服(我个人是喜欢代码看起来比较舒服),也不是为了使代码看起来更牛叉(我个人是喜欢代码看起来比较牛叉),而是为了是代码的可拓展性更高,可阅读性更高,修改起来比较方便。

   当根据需求要产生不同的东西的时候,并且需求种类很多的情况下。

三、举个例子

  假设有一个买家,他想买衣服、想买裤子、想买鞋子。他就要亲自去干很多事情。

  假设有很多不赚差价的中间商,他们可以帮你买衣服,帮你买裤子,帮你买鞋子。那么现在这个买家,他不用自己去找衣服厂家买衣服,他可以找这个不赚差价的中间商,中间商会帮他处理一切细节,最终给他一件衣服。

    首先我们先把这些中间商给实现了  

 1         /// <summary>
 2         /// 中间商接口
 3         /// </summary>
 4         public interface IMiddleman
 5         {
 6             string Shopping();
 7         }
 8 
 9         /// <summary>
10         /// 中间商接口基类
11         /// </summary>
12         public abstract class BaseMiddleman : IMiddleman
13         {
14             public abstract string Shopping();
15         }
16 
17         /// <summary>
18         /// 衣服中间商
19         /// </summary>
20         public class ClothesMiddleman : BaseMiddleman
21         {
22             public override string Shopping()
23             {
24                 return "给你买来了衣服";
25             }
26         }
27 
28         /// <summary>
29         /// 裤子中间商
30         /// </summary>
31         public class TrousersMiddleman : BaseMiddleman
32         {
33             public override string Shopping()
34             {
35                 return "给你买来了裤子";
36             }
37         }
38 
39         /// <summary>
40         /// 鞋子中间商
41         /// </summary>
42         public class ShoesMiddleman : BaseMiddleman
43         {
44             public override string Shopping()
45             {
46                 return "给你买来了鞋子";
47             }
48         }

  为什么这里要定义接口,因为可能有不同的中间商嘛。那为什么有基类,因为有部分中间商干的事情是一样的嘛。

  其实中间商不一定只给你买衣服,他还可能给你全套服务,比如售前、售后、询底价、试穿。。。那只需要拓展一下接口,基类实现一下,个别实现不同的话重写一下,就OK了。

  那么现在要买衣服只需要

  

 1 static void Main(string[] args)
 2         {
 3             var cloths = new FactoryDemo.ClothesMiddleman().Shopping();
 4             var trousers = new FactoryDemo.TrousersMiddleman().Shopping();
 5             var shoes = new FactoryDemo.ShoesMiddleman().Shopping();
 6             Console.WriteLine(cloths);
 7             Console.WriteLine(trousers);
 8             Console.WriteLine(shoes);
 9 
10             Console.ReadKey();
11         }

   

  那么问题来了,虽然这个买家不用自己亲自去买衣服了,但他还是要找不同的中间商买,那就很麻烦。(好懒啊!)

  现在有这么个中间商管理员,你只需要告诉这个中间商管理员,你想要什么,他会去给你找不同的中间商,最终给你想要的。

  

 1         /// <summary>
 2         /// 中间商管理员
 3         /// </summary>
 4         public static class MiddlemanManager
 5         {
 6             /// <summary>
 7             /// 购物类别枚举
 8             /// </summary>
 9             public enum EShoppingType
10             {
11                 衣服,
12                 裤子,
13                 鞋子
14             }
15 
16             static Dictionary<EShoppingType, IMiddleman> _ManagerDic;
17 
18             /// <summary>
19             /// 中间商管理员库
20             /// </summary>
21             static Dictionary<EShoppingType, IMiddleman> ManagerDic
22             {
23                 get
24                 {
25                     if (_ManagerDic == null)
26                     {
27                         lock (typeof(MiddlemanManager))
28                         {
29                             if (_ManagerDic == null)
30                             {
31                                 _ManagerDic = new Dictionary<EShoppingType, IMiddleman>()
32                                 {
33                                     { EShoppingType.衣服, new ClothesMiddleman() },
34                                     { EShoppingType.裤子, new TrousersMiddleman() },
35                                     { EShoppingType.鞋子, new ShoesMiddleman() }
36                                 };
37                             }
38                         }
39                     }
40                     return _ManagerDic;
41                 }
42             }
43 
44             /// <summary>
45             /// 获取实例化的中间商
46             /// </summary>
47             public static IMiddleman Create(EShoppingType type)
48             {
49                 return ManagerDic[type];
50             }
51         }

  好了,这下管理员也有了,买家只需要找管理员要东西就行了。这里管理员的库用的是硬编码的字典,其实还有很多方式,比如常用的反射。我更喜欢硬编码的字典、XML配置文件、数据库等。

 1         static void Main(string[] args)
 2         {
 3             var cloths = FactoryDemo.MiddlemanManager.Create(FactoryDemo.MiddlemanManager.EShoppingType.衣服).Shopping();
 4             var trousers = FactoryDemo.MiddlemanManager.Create(FactoryDemo.MiddlemanManager.EShoppingType.裤子).Shopping();
 5             var shoes = FactoryDemo.MiddlemanManager.Create(FactoryDemo.MiddlemanManager.EShoppingType.鞋子).Shopping();
 6             Console.WriteLine(cloths);
 7             Console.WriteLine(trousers);
 8             Console.WriteLine(shoes);
 9 
10             Console.ReadKey();
11         }

  好了,这样只需要找管理员,告诉这个管理员我需要什么,其他的都不用买家去做,一条龙服务。

四、结语

  第一次写博客,写了这么多,发现写写文章还是蛮累的,把想法表达出来还真的蛮难的。

原文地址:https://www.cnblogs.com/yanghaoRoom/p/10671536.html