IMZRH的日志

努力成为一个有用的人

导航

31天重构指南之十二:分解依赖

Posted on 2009-09-29 15:41  张荣华  阅读(308)  评论(0编辑  收藏  举报

如果你要在你的代码中加入单元测试但有一部分代码是你不想测试的,那么你应用使用今天的重构。在下面的例子中我们应用静态类来完成某些工作,但问题是在单元测试时我们无法mock静态类,所以我们只能引入静态类的装饰接口(wrapper interface)来分解对静态类的依赖。

   1: public class AnimalFeedingService
   2: {
   3:     private bool FoodBowlEmpty { get; set; }
   4:  
   5:     public void Feed()
   6:     {
   7:         if (FoodBowlEmpty)
   8:             Feeder.ReplenishFood();
   9:  
  10:         // more code to feed the animal
  11:     }
  12: }
  13:  
  14: public static class Feeder
  15: {
  16:     public static void ReplenishFood()
  17:     {
  18:         // fill up bowl
  19:     }
  20: }
要对上述代码应用分解依赖重构,我们要做的是添加一个接口和一个实现类,在实现类中调用静态类的方法,所以说具体做什么事情没有改变,改变的只是形式,但这样做的一个好处是增加了
了代码的可测试性。
   1: public class AnimalFeedingService
   2: {
   3:     public IFeederService FeederService { get; set; }
   4:  
   5:     public AnimalFeedingService(IFeederService feederService)
   6:     {
   7:         FeederService = feederService;
   8:     }
   9:  
  10:     private bool FoodBowlEmpty { get; set; }
  11:  
  12:     public void Feed()
  13:     {
  14:         if (FoodBowlEmpty)
  15:             FeederService.ReplenishFood();
  16:  
  17:         // more code to feed the animal
  18:     }
  19: }
  20:  
  21: public interface IFeederService
  22: {
  23:     void ReplenishFood();
  24: }
  25:  
  26: public class FeederService : IFeederService
  27: {
  28:     public void ReplenishFood()
  29:     {
  30:         Feeder.ReplenishFood();
  31:     }
  32: }
  33:  
  34: public static class Feeder
  35: {
  36:     public static void ReplenishFood()
  37:     {
  38:         // fill up bowl
  39:     }
  40: }
 在应用了分解依赖模式后,我们就可以在单元测试的时候mock一个IFeederService对象并通过AnimalFeedingService的构造函数传递给它。
原文链接:http://www.lostechies.com/blogs/sean_chambers/archive/2009/08/12/refactoring-day-12-break-dependencies.aspx