三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> 敏捷开发 -> 敏捷软件开发 – ISP 接口隔离原则 -> 正文阅读
 

[敏捷开发]敏捷软件开发 – ISP 接口隔离原则

敏捷软件开发 – ISP 接口隔离原则   如果类的接口不是内聚的,就表示该类具有“胖”接口。换句话说,类的“胖”接口可以分解成多组方法。每一组方法服务于一组不同的客户程序。
  ISP承认有一些对象确实需要有非内聚的接口,但是ISP建议客户程序不应该看到它们作为单一的类存在。相反,客户程序看到的应该是多个具有内聚接口的抽象基类。
接口污染
  考虑一个安全系统。在这个系统中,有一些Door对象,可以被加锁和解锁,并且Door对象知道自己是开着还是关着。这个Door编码成一个接口,这样客户程序就可以使用那些符合Door接口的对象,而不需要依赖于Door的特定实现。

public interface Door
{
    void Lock();
    void Unlock();
    bool IsDoorOpen();
}

  现在,考虑一个这样的实现,TimedDoor,如果门开着的时间过长,它就会发出警报声。为了实现这一点,TimedDoor对象需要和另外一个名为Timer的对象交互。

public class Timer
{
    public void Register(int timeout,TimerClient client)
    {}
}

public interface TimerClient
{
    void TimeOut();
}

  如果一个对象希望得到超时通知,它可以调用Timer的Register函数。该函数有两个参数,一个是超时时间,另一个是指向TimerClient对象的引用,其TimeOut函数会在超市到达时被调用。
  如何把TimerClient类和TimedDoor类联系起来,才能在超时时通知TimedDoor中相应的处理代码呢?
  常见的解决方案是,其中Door继承了TimerClient,因此TimedDoor也就继承了TimeClient。这就保证了TimerClient可以把自己注册到Timer中,并且可以接收TimeOut消息。

  这种做法的问题是,现在Door依赖于TimerClient了。可是并不是所有种类的Door都需要定时功能。事实上,最初的Door抽象类和定时功能没有任何关系。如果创建了无需定时功能的Door的派生类,那么在这些派生类中就必须要提供TimeOut方法的退化实现,这就可能违反ISP。此外,使用这些派生类的应用程序及时不使用TimerClient类的定义,也必须要引入它。这样就具有了不必要的复杂性以及不必要的重复性的臭味。
分离客户就是分离接口
  Door接口和TimerClient接口是被完全不同的客户程序使用的。Timer使用TimerClient,而操作门的类使用Door。既然客户程序是分离的,所以接口也应该保持分离。
  不应该强迫客户程序依赖并未使用的方法。
  如果强迫客户程序依赖于那些它们不使用的方法,那么这些客户程序就面临着由于这些未使用的方法的改变所带来的变更。这无意中导致了所有客户程序之间的耦合。换种说法,如果一个客户程序依赖于一个含有它不使用的方法的类,但是其他客户程序却确实要使用该方法,那么当其他客户要求这个类改变时,就会影响到这个客户程序。我们希望尽可能地避免这种耦合,因此我们希望分离接口。
类接口和对象接口
  再次考虑一下TimedDoor。它具有两个独立的接口,被两个独立的客户-Timer以及Door的使用者-使用。因此实现这两个接口需要操作同样的数据,所以这两个接口必须在同一个对象中实现。那么怎样才能遵循ISP呢?怎样才能分离必须在一起实现的接口呢?
  那就是一个对象的客户不必通过该对象的接口去访问它,也可以通过委托或者通过该对象的基类去访问它。
通过委托(适配器)分离接口
  一个解决方案是创建一个派生自TimerClient的对象,并把对该对象的请求传递给TimedDoor。
  当TimedDoor想要向Timer对象注册一个超时请求时,它就创建一个DoorTimerAdapter并且把它注册给Timer。当Timer对象发送TimeOut消息给DoorTimerAdapter时,DoorTimerAdapter把这个消息传递给TimedDoor。

  这个解决方案遵循了ISP原则,并且避免了Door的客户程序和Timer之间的耦合。即使对Timer进行了改变,也不会影响到任何Door的使用者。此外TimedDoor不必具有和TimerClient一样的接口。DoorTimerAdapter将TimerClient接口转换为TimedDoor接口。因此,这是一个通用的解决方案。
  不过,这个解决方案还是有些不太优雅。每次想去注册一个超时请求时,都要去创建一个新的对象。同时,类型转换会倒置一些很小但仍然存在的运行时间和内存的开销。
使用多重继承分离接口

   在这个模型中,TimedDoor同时继承了Door和TimerClient。尽管这两个基类的客户程序都可以使用TimedDoor,但是实际上却都不再依赖于TimedDoor。这样,它们就通过分离的接口使用同一对象。
  通常都会优先使用这个解决方案。
结论
  胖类会导致它们的客户程序之间产生不正常的并且有害的耦合关系。当一个客户程序要求该胖类进行一个改动时,会影响到所有其他的客户程序。因此,客户程序应该仅仅依赖于它们实际调用的方法。通过把胖类的接口分解为多个特定于客户程序的接口,可以实现这个目标。每个特定于客户程序的接口仅仅声明它的特定客户或者客户组调用的那些函数。接着,该胖类就可以继承所有特定于客户程序的接口,并实现它们。这就解除了客户程序和它们没有调用的方法间的依赖关系,并使客户程序之间互不依赖。
摘录自:[美]RobertC.Martin、MicahMartin著,邓辉、孙鸣译 敏捷软件开发原则、模式与实践(C#版修订版) [M]、人民邮电出版社,2013、115-121、
  敏捷开发 最新文章
Git~分支真的很轻
分享一个开源免费、目前最好的API接口管理平
论「版本号」的正确使用方式
GitLab~当它是一个源代码管理工具时
Maven依赖解析
如何基于 eolinker 的进行接口管理
敏捷开发心得2
谈一下我们是如何开展code review的
使用Hudson进行持续集成
gitlab+gerrit+jenkins持续集成框架
上一篇文章      下一篇文章      查看所有文章
加:2016-09-13 15:34:16  更:2017-05-17 02:51:17 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-17 1:08:54
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库