重构第12天 分解依赖(Break Dependencies)
理解:“分解依赖” 是指对部分不满足我们要求的类和方法进行依赖分解,通过装饰器来达到我们需要的功能。
详解:今天我们所讲的这个重构方法对于单元测试是非常有用的。如果你要在你的代码中加入单元测试但有一部分代码是你不想测试的,那么你应用使用这个的重构。
这个例子中我们客户端使用了一个静态类来完成部分工作,但是问题就在于进行单元测试的时候,我们无法模拟静态类进行测试。为了使单元测试能够进行,我们用一个接口来包装这个静态类来完成静态类的依赖分解。
重构前代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ReflectorDemo
{
public class AnimalFeedingService
{ private bool FoodBowlEmpty { get; set; } public void Feed()
{
if (FoodBowlEmpty)
{
Feeder.ReplenishFood();
}
// more code to feed the animal
}
} public static class Feeder
{ public static void ReplenishFood()
{
// fill up bowl
}
}
}
我们添加一个接口和一个实现类,在实现类中调用静态类的方法,所以说具体做什么事情没有改变,改变的只是形式,但这样做的一个好处是增加了了代码的可测试性。在应用了分解依赖模式后,我们就可以在单元测试的时候mock一个IFeederService对象并通过AnimalFeedingService的构造函数传递给它。这样就可以完成我们需要的功能。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ReflectorDemo
{
public class AnimalFeedingService
{ public IFeederService FeederService { get; set; } private bool FoodBowlEmpty { get; set; } public AnimalFeedingService(IFeederService feederServices)
{
FeederService = feederServices;
} public void Feed()
{
if (FoodBowlEmpty)
{
FeederService.ReplenishFood();
}
// more code to feed the animal
}
} public static class Feeder
{ public static void ReplenishFood()
{
// fill up bowl
}
}
public interface IFeederService
{
void ReplenishFood();
} public class FeederService : IFeederService
{ public void ReplenishFood()
{ Feeder.ReplenishFood();
}
}
}
这样,我们在单元测试的时候就可以模拟(MOCK)一个IFeederService 接口的实例,通过AnimalFeedingService 的构造函数传进去。
这个重构在很多时候和设计模式中的一些思想类似,使用中间的装饰接口来分解两个类之间的依赖,对类进行装饰,然后使它满足我们所需要的功能。
重构第12天 分解依赖(Break Dependencies)的更多相关文章
- 重构第22天 分解方法(Break Method)
理解:如果一个功能,里面比较复杂,代码量比较多,我们就可以把这个功能分解成多个小的method,每个方法实现该功能的一个小小的部分,并且方法命名成容易理解,和方法内容相关的名称,更有助于维护和可读性提 ...
- dagger2系列之依赖方式dependencies、包含方式(从属方式)SubComponent
本篇是实战文章,从代码的角度分析这两种方式.本文参考自下列文章: http://www.jianshu.com/p/1d42d2e6f4a5 http://www.jianshu.com/p/94d4 ...
- 重构改善既有代码设计--重构手法12:Extract Class (提炼类)
某个类做了应该由2个类做的事.建立一个新类,将相关的字段和函数从旧类搬移到新类. 动机:一个类应该是一个清楚地抽象,处理一些明确的责任.但是在实际工作中,类会不断成长扩展.你会在这儿加入一些功能,在哪 ...
- 重构第24天 分解复杂的判断(Remove Arrowhead Antipattern)
理解: 当你的代码中有很深的嵌套条件时,花括号就会在代码中形成一个长长的箭头.我们经常在不同的代码中看到这种情况,并且这种情况也会扰乱代码的可读性. 如下代码所示,HasAccess方法里面包含一些嵌 ...
- 重构第14天 分离职责(Break Responsibilities)
理解:面向对象的五大特征: SOLID,其中S就是职责单一原则.分离职责指当一个类有许多职责时,将部分职责分离到独立的类中,这样也符合面向对象的五大特征之一的单一职责原则,同时也可以使代码的结构更加清 ...
- C#重构经典全面汇总
C#重构经典全面汇总 1. 封装集合 概念:本文所讲的封装集合就是把集合进行封装,仅仅提供调用端须要的接口. 正文:在非常多时候,我们都不希望把一些不必要的操作暴露给调用端,仅仅须要给它所须要的操作 ...
- Gradle 1.12用户指南翻译——第五十章. 依赖管理
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上 ...
- npm安装依赖包 --save-dev 和 --save; package.json的devDependencies和dependencies 的区别!
以前一直在纠结一个npm安装的包依赖管理的问题.是这样的: 我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,他们是:--save- ...
- 【Java重构系列】重构31式之封装集合
2009年,Sean Chambers在其博客中发表了31 Days of Refactoring: Useful refactoring techniques you have to know系列文 ...
随机推荐
- Centos7 改名问题
先看这篇 深入理解Linux修改hostname http://www.cnblogs.com/kerrycode/p/3595724.html 我使用如下方法 http://www.linuxid ...
- 【转帖】四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho
四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho 1 BI系统的简述 从技术角度来说 BI 包含了 ETL.DW.OLAP.DM等多环节.简单的说就是把交易系统 ...
- Crystal Reports 支持的纸张种类
DefaultPaperSize Paper10x14 254 x 355.6 mm Paper11x17 279.4 x 431.8 mm PaperA3 A3 ?,297 x 420 mm Pap ...
- 高效开发Android App的10个建议
假如要Google Play上做一个最失败的案例,那最好的秘诀就是界面奇慢无比.耗电.耗内存.接下来就会得到用户的消极评论,最后名声也就臭了.即使你的应用设计精良.创意无限也没用. 耗电或者内存占用等 ...
- swift 如何删除subviews
scrollView.subviews.map { (var view) -> () in if (view is UIButton) { view.removeFromSuperview() ...
- ffrpc的php客户端lib
摘要: ffrpc 是c++异步通讯库,使用ffrpc可以非常容易的构建服务器程序.为了使用方便,ffrpc提供了python.php的客户端lib,这样使用php于c++构建的server也是顺手拈 ...
- Mac eclipse找不到source的解决办法
因为要搞hadoop,最终还是逃不过写java的命运... eclipse里想查具体函数源代码时,如果报错说找不到源: 试试ls -l which java,在这个目录周围看看能不能找到src.zip ...
- thinkphp的伪静态化
1. 设置默认的控制器和模块 // 绑定访问Admin模块 define('BIND_MODULE','Home'); // 绑定访问Index控制器 define('BIND_CONTROLLER' ...
- 关于"The dependency was added by the project system and cannot be removed" Error
阅读一个简单地工程代码,其中一个工程BaseCode是 static lib,另一个工程RunBaseCode使用该lib,但在工程设置的“Linker\Input\AdditionalDepende ...
- 使用aspose.cell导出excel需要注意什么?
1.如果导出的数据源是汇总出来的,最好方法是将数据源放到缓存里面,当基本数据源变化的时候,在改变数据2.使用模板导出EXCEL,这样很多样式可以在模板文件里面直接设置,例如:默认打开页签,让列头固定3 ...