zoukankan      html  css  js  c++  java
  • 重构第12天 分解依赖(Break Dependencies)

    理解:“分解依赖” 是指对部分不满足我们要求的类和方法进行依赖分解,通过装饰器来达到我们需要的功能。

    详解:今天我们所讲的这个重构方法对于单元测试是非常有用的。如果你要在你的代码中加入单元测试但有一部分代码是你不想测试的,那么你应用使用这个的重构。

             这个例子中我们客户端使用了一个静态类来完成部分工作,但是问题就在于进行单元测试的时候,我们无法模拟静态类进行测试。为了使单元测试能够进行,我们用一个接口来包装这个静态类来完成静态类的依赖分解。

             重构前代码:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace ReflectorDemo
     7 {
     8   public  class AnimalFeedingService
     9     {
    10 
    11       private bool FoodBowlEmpty { get; set; }
    12 
    13       public void Feed()
    14       {
    15           if (FoodBowlEmpty)
    16           {
    17               Feeder.ReplenishFood();
    18           }
    19           // more code to feed the animal
    20       }
    21     }
    22 
    23     public static class Feeder
    24     {
    25 
    26         public static void ReplenishFood()
    27         {
    28             // fill up bowl
    29         }
    30     }
    31 }

    我们添加一个接口和一个实现类,在实现类中调用静态类的方法,所以说具体做什么事情没有改变,改变的只是形式,但这样做的一个好处是增加了了代码的可测试性。在应用了分解依赖模式后,我们就可以在单元测试的时候mock一个IFeederService对象并通过AnimalFeedingService的构造函数传递给它。这样就可以完成我们需要的功能。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace ReflectorDemo
     7 {
     8     public class AnimalFeedingService
     9     {
    10 
    11         public IFeederService FeederService { get; set; }
    12 
    13         private bool FoodBowlEmpty { get; set; }
    14 
    15         public AnimalFeedingService(IFeederService feederServices)
    16         {
    17             FeederService = feederServices;
    18         }
    19 
    20         public void Feed()
    21         {
    22             if (FoodBowlEmpty)
    23             {
    24                 FeederService.ReplenishFood();
    25             }
    26             // more code to feed the animal
    27         }
    28     }
    29 
    30     public static class Feeder
    31     {
    32 
    33         public static void ReplenishFood()
    34         {
    35             // fill up bowl
    36         }
    37     }
    38 public interface IFeederService
    39     {
    40         void ReplenishFood();
    41     }
    42 
    43 
    44     public class FeederService : IFeederService
    45     {
    46 
    47         public void ReplenishFood()
    48         {
    49 
    50             Feeder.ReplenishFood();
    51         }
    52     }
    53 }

    这样,我们在单元测试的时候就可以模拟(MOCK)一个IFeederService 接口的实例,通过AnimalFeedingService 的构造函数传进去。

    这个重构在很多时候和设计模式中的一些思想类似,使用中间的装饰接口来分解两个类之间的依赖,对类进行装饰,然后使它满足我们所需要的功能。

  • 相关阅读:
    并不对劲的网络流
    并不对劲的[noi2006]网络收费
    并不对劲的spoj1812
    48.孩子们的游戏(圆圈中最后剩下的数)
    47.扑克牌顺子
    46.翻转单词顺序
    45.左旋转字符串
    44.和为S的两个数字
    43.和为S的连续正数序列
    42.数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/yplong/p/5318576.html
Copyright © 2011-2022 走看看