【抽象那些事】不完整的抽象&多方面抽象&未用的抽象&重复的抽象

mark

不完整的抽象

抽象未支持全部互补或相关的方法时,将致使这种坏味。程序员

为何要有完整的抽象?

一种重要的抽象实现手法是建立内聚而完整的抽象。抽象未支持相关的方法时,可能会影响抽象的内聚性和完整性。若是抽象只支持部分相关的方法,其使用者就可能不得不本身去实现其余的功能。客户程序可能尝试直接访问抽象的内部实现细节,此时带来的反作用是违反封装原则。编程

一些常见的互补方法对

Min/Max Open/Close Create/Destroy Get/Set
Read/Write Print/Scan First/Last Begin/End
Start/Stop Lock/Unlock Show/Hide Up/Down
Source/Target Insert/Delete First/Last Push/Pull
Enable/Disable Acquire/Release Left/Right On/Off

现实考虑

###禁止特定行为c#

设计人员可能有意识地作出不提供堆成或配套方法的设计决策。例如在只读集合中,包含Add()方法,而不包含Remove()方法。微信

使用单个方法而不是成对的方法

例如用SetEnabled(bool)替换Enable()和Disable(),传入true表明启用,fasle表明禁用。框架

多方面抽象

抽象被赋予不止一项职责时,将致使这种坏味。ide

##为何不能够有多方面抽象?工具

单一职责原则指出,抽象必须承担单一而明确的职责,且必须彻底封装该职责。抽象承担了多种职责时,意味着它将受多种缘由的影响而须要修改,设计的修改频率与其缺陷数之间存在很强的正相关关系。这意味着多方面抽象存在的缺陷可能更多。学习

多方面抽象的潜在缘由

通用抽象

引入使用通用名(如Item,Order,Product,Image)的抽象时,它经常会成为占位符,用于提供全部相关(但未必属于它)的功能。抽象的命名表明了这个抽象的职责,命名太通用,随着系统的迭代,抽象会慢慢承担多种职责。感同身受!!!ui

未按期重构

对类进行了大量修改而没有按期重构,久而久之,可能就会在类中引入了额外的职责。spa

混合关注点

没有对关注点分离给予足够的重视。

重构建议

类承担了多种职责时,就不是内聚的。可使用“提取类”来进行重构。

mark

未用的抽象

建立的抽象未用(未被直接使用或继承)时,将致使这种坏味。有如下两种表现形式:

  • 未引用的抽象:未用的具体类
  • 鳏寡抽象:没有任何派生抽象的接口/抽象类

为何不能够有未用的抽象?

设计中的抽象未被使用,就没有发挥任何做用,所以违反了抽象原则。未实现的抽象类和接口时多余的或凭空想象出来的归纳,所以是不须要的。

##未用的抽象潜在缘由

凭空想象的设计

试图设计"永不过期"的系统或在其中包含"将来可能用得着"的抽象时,将致使这种坏味。

不断变化的需求

需求不断变化,为知足早期需求而建立的抽象可能已经再也不须要。若是将其留在设计中,它将变成未用的抽象。

维护过程当中留下的垃圾

维护或重构时,若是不清理旧的抽象,可能留下未引用的抽象。这点深有体会,因此一直要求组员在重构的过程当中,必定要把旧代码删除。若是不这样作,过时的和未用的代码将致使代码库急剧膨胀,重构的代码和未重构的代码纠缠在一块儿,代码的可理解性、阅读体验极差。并且若是你重构的旧代码你不负责删除,其余人就更不知道如何下手了,长此以往这些旧代码就会变成BUG的温床。注释掉旧代码也不是一个好的选择,太影响阅读体验。其次,如今的代码版本控制工具功能强大,即便删除错了代码,也能够经过版本控制工具找回。因此旧代码必须死。

担忧破坏既有代码

不肯定是否还有其余代码在使用想要删除的旧代码。

重构建议

将未用的抽象从设计中删除。对于可能还有客户程序在使用的API,直接删除不可行,可将这些抽象标记为''过时的''或"已摒弃",明确地指出在新开发的客户程序中不得使用它们。

[Obsolete]
public class Report
{
}

现实考虑

类库和框架一般以抽象类或接口的方式提供扩展点,这些抽象类可能在库或框架中未被使用,但它们是供客户程序使用的扩展点,所以不属于未用的抽象。

重复的抽象

两个抽象的名称、实现或二者相同时,将致使这种坏味。

  • 名称相同

    两个不一样的抽象重名将影响可理解性。

  • 实现相同

    多个抽象的成员定义在语义上相同,但在设计上没有捕获并使用这些实现中相同的元素。在继承层析结构中,若是多个兄弟抽象的实现相同,可能意味着存在的是"未归并的层次结构"坏味。

  • 名称实现都相同

##为何不能够有重复的抽象?

重复代码是软件万恶之首。因此咱们要极力避免重复。

若是多个抽象的名称相同,将影响设计的可理解性:客户代码开发人员将不知道使用哪一个抽象。

若是多个抽象的实现相同(代码相同),将难以维护:修改其中一个抽象的实现时,经常须要修改其它全部重复抽象的实现。这不只增长了修改负担,还可能引入难以发现的微小BUG。为缩小修改范围,必须尽量避免重复。

重复的抽象潜在缘由

复制粘贴编程手法

CV程序员复制并粘贴代码,而不该用合适的抽象。

即兴维护

通过多年的修复或改进后,软件将包含"残留",其中有大量重复的代码。

交流不顺畅

不一样时期一般由不一样的人员负责维护软件,他们对软件的了解不完全,编写了原来就有的类或方法,致使软件包含重复的代码。

###类被声明为不可扩展的

类被声明为不可扩展的,没法重用代码,只能复制代码,建立修订版本。

重构建议

对于名称相同的重复抽象,能够将其中一个抽象改成不一样的名称。

对于实现相同的重复抽象,若是实现彻底相同,可将其中一个抽象删除。若是实现稍有差别,可将相同的实现归并到另外一个类中:这能够是层次结构中的基类,也能够是重复的抽象可引用或使用的既有类或新类。

现实考虑

适应变化

致使重复抽象的一个缘由是,要同时支持同步和非同步变种。

在不一样的上下文中使用相同的类型名

对于大型系统,创建彻底统一的领域模型要么不可行要么不划算。领域驱动设计提供的一种解决方案是,将大型系统分红多个"界限上下文"。采用这种方式,不一样上下文中的模型可能包含同名的类型,可是这是能够接受的。

语言未提供重复避免支持

在JDK中,有不少的重复的方法和类,这是由于没有对基本类型提供泛型支持。可是在.Net中就不会有这么多重复的方法和类,由于C#对基本类型提供了泛型支持。

参考:《软件设计重构》

<strong> <div class="content"> <div>做者:<a style="color: red; font-family: 微软雅黑; text-decoration: none" href="http://songwenjie.cnblogs.com/" target="_blank">撸码那些事</a></div> <div>来源:<a style="color: red; font-family: &quot;Microsoft YaHei&quot;; text-decoration: none" href="http://songwenjie.cnblogs.com/" target="_blank">http://songwenjie.cnblogs.com/</a> <div>声明:本文为博主学习感悟总结,水平有限,若是不当,欢迎指正。若是您认为还不错,不妨点击一下下方的<span onclick="Digg();">【<font color=red>推荐</font>】</span>按钮,谢谢支持。转载与引用请注明出处。</div> <div>微信公众号: <img src="http://songwenjie.vip/blog/180511/AFdec5f65k.jpg?imageslim" title="关注公众号,获取最新更新"/></div> </strong> </div>

相关文章
相关标签/搜索