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

    一、背景

      最近在工作中,要修改离职的同事的代码,发现有一个函数代码长度达到了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         }

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

    四、结语

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

  • 相关阅读:
    Feature分支
    Bug分支
    分支管理策略
    解决冲突
    创建与合并分支
    分支管理
    Java并发与多线程教程(1)
    Java Thread(线程)案例详解sleep和wait的区别
    Spring在Thread中注入Bean无效的解决方式
    浅谈Java中的hashcode方法
  • 原文地址:https://www.cnblogs.com/yanghaoRoom/p/10671536.html
Copyright © 2011-2022 走看看