您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 面向对象的设计法则系列--BobTarr
面向对象的设计法则系列BobTarr著版本:0.1.0编写:outmyth日期:2002-11-20页数:共19页WebScope小组(C)2002-2003WebScopeGroup,AllRightsReserved。修改说明日期版本号摘要作者2002-11-200.1.0创建outmythWebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。目录1:优先使用(对象)组合,而非(类)继承3组合的优点和缺点4继承4继承的优点和缺点4Coad规则5继承/组合示例15继承/组合示例27继承/组合示例38继承/组合示例49继承/组合总结92:针对接口编程,而非(接口的)实现10接口10实现继承和接口继承10接口的好处11接口实例123:开放-封闭法则(OCP)12开放-封闭法则12OCP示例13相关法则15(a)单选法则154:Liskov替换法则(LSP)16Liskov替换法则16LSP示例17总结19WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。【译者注】本文主要是以BobTarr的文章作为翻译的主线(黑色),GOF(紫色),C++View上翻译RobertMartin的文章(褐色)和Webscope(蓝色和绿色)上的文章以及译者的见解为辅。1:优先使用(对象)组合,而非(类)继承[FavorCompositionOverInheritance]组合(对象)组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。将功能委托给所组合的一个对象,从而获得新功能。有些时候也称之为“聚合”(aggregation)或“包容”(containment),尽管有些作者对这些术语赋予了专门的含义例如:聚合:一个对象拥有另一个对象或对另一个对象负责(即一个对象包含另一个对象或是另一个对象的一部分),并且聚合对象和其所有者具有相同的生命周期。(译者注:即所谓的“同生共死”关系)(可参见GOF的DesignPatterns:ElementsofReusableObject-OrientedSoftwareWebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。的引言部分)包容:一种特殊类型的组合,对于其它对象而言,容器中的被包含对象是不可见的,其它对象仅能通过容器对象来访问被包含对象。(Coad)包含可以通过以下两种方式实现:根据引用(Byreference)根据值(Byvalue)C++允许根据值或引用来实现包含。但是在Java中,一切皆为对象的引用!组合的优点和缺点优点:容器类仅能通过被包含对象的接口来对其进行访问。“黑盒”复用,因为被包含对象的内部细节对外是不可见。封装性好。实现上的相互依赖性比较小。(译者注:被包含对象与容器对象之间的依赖关系比较少)每一个类只专注于一项任务。通过获取指向其它的具有相同类型的对象引用,可以在运行期间动态地定义(对象的)组合。缺点:从而导致系统中的对象过多。为了能将多个不同的对象作为组合块(compositionblock)来使用,必须仔细地对接口进行定义。继承(类)继承是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。泛化类(超类)可以显式地捕获那些公共的属性和方法。特殊类(子类)则通过附加属性和方法来进行实现的扩展。继承的优点和缺点优点:WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。容易进行新的实现,因为其大多数可继承而来。易于修改或扩展那些被复用的实现。缺点:破坏了封装性,因为这会将父类的实现细节暴露给子类。“白盒”复用,因为父类的内部细节对于子类而言通常是可见的。当父类的实现更改时,子类也不得不会随之更改。从父类继承来的实现将不能在运行期间进行改变。Coad规则仅当下列的所有标准被满足时,方可使用继承:子类表达了“是一个…的特殊类型”,而非“是一个由…所扮演的角色”。子类的一个实例永远不需要转化(transmute)为其它类的一个对象。子类是对其父类的职责(responsibility)进行扩展,而非重写或废除(nullify)。子类没有对那些仅作为一个工具类(utilityclass)的功能进行扩展。对于一个位于实际的问题域(ProblemDomain)的类而言,其子类特指一种角色(role),交易(transaction)或设备(device)。继承/组合示例1“是一个…的特殊类型”,而非“是一个由…所扮演的角色”失败。乘客是人所扮演的一种角色。代理人亦然。永远不需要转化失败。随着时间的发展,一个Person的子类实例可能会从Passenger转变成Agent,WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。再到AgentPassenger。扩展,而非重写和废除通过。不要扩展一个工具类通过。在问题域内,特指一种角色,交易或设备失败。Person不是一种角色,交易或设备。继承并非适用于此处!使用组合进行挽救!WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。继承/组合示例2“是一个…的特殊类型”,而非“是一个由…所扮演的角色”通过。乘客和代理人都是特殊类型的人所扮演的角色。永远不需要转化通过。一个Passenger对象将保持不变;Agent对象亦然。扩展,而非重写和废除通过。不要扩展一个工具类通过。在问题域内,特指一种角色,交易或设备通过。PersonRole是一种类型的角色。继承适用于此处!WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。继承/组合示例3“是一个…的特殊类型”,而非“是一个由…所扮演的角色”通过。预订和购买都是一种特殊类型的交易。永远不需要转化通过。一个Reservation对象将保持不变;Purchase对象亦然。扩展,而非重写和废除通过。不要扩展一个工具类通过。在问题域内,特指一种角色,交易或设备通过。是一种交易。继承适用于此处!WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。继承/组合示例4“是一个…的特殊类型”,而非“是一个由…所扮演的角色”失败。预订不是一种特殊类型的observable。永远不需要转化通过。一个Reservation对象将保持不变。扩展,而非重写和废除通过。不要扩展一个工具类失败。Observable就是一个工具类。在问题域内,特指一种角色,交易或设备不适用。Observable是一个工具类,并非一个问题域的类。。继承并非适用于此处!继承/组合总结组合与继承都是重要的重用方法在OO开发的早期,继承被过度地使用随着时间的发展,我们发现优先使用组合可以获得重用性与简单性更佳的设计当然可以通过继承,以扩充(enlarge)可用的组合类集(thesetofcomposableclasses)。因此组合与继承可以一起工作但是我们的基本法则是:优先使用对象组合,而非(类)继承[FavorCompositionOverInheritance]WebScopeGroupForum小组(C)2002-2003WebScopeGroup,AllRightsReserved。2:针对接口编程,而非(接口的)实现[ProgramToAnInterface,NotAnImplementation]接口接口是一个对象在对其它的对象进行调用时所知道的方法集合。(译者注:GOF也给出了接口的定义,即对象接口描述了该对象所能接受的全部请求的集合。可参见GOF的DesignPatterns:ElementsofReusableObject-OrientedSoftware的引言部分)一个对象可以有多个接口(实际上,接口是对象所有方法的一个子集)类型是对象的一个特定的接口。不同的对象可以具有相同的类型,而且一个对象可以具有多个不同的类型。(译者注:GOF论述接口与类型之间的关系,即若一个对象接受“Window”接口所定义的所有操作请求,则我们就说该对象具有“Window”类型。对象接口的某部分可以用某个类型来刻画,而其它部分则可用其它类型刻画(也就是说类型是组成和划分接口的基本单位)。两个类型相同的对象只需要共享它们的部分接口。接口可以包含其它接口作为子集:当一个类型的接口包含另一个类型的接口时,我们就说它是另一个类型的子类型(subtype),另一个类型称之为它的超类型(supertype)。我们常说子类型继承了它的超类型的接口。可参见GOF的DesignPatterns:ElementsofReusableObject-OrientedSoftware的引言部分。)一个对象仅能通过其接口才会被其它对象所了解。某种意义上,接口是以一种非常局限的方式,将“是一种…”表达为“一种支持该接口的…”。接口是实现插件化(pluggability)的关键(译者注:对象的类和对象的类型的差别:一个对象的类定义了对象是怎样实现的,同时也定义了对象的内部状态和对象作的实现。但是对象的类型只与其接口有关。接口即对象能响应的请求的集合。当然对象的类和类型是有系统关系的。因为类定义了对象所能执行的操作。也定义了对象的类型。当我们说一个对象是一个类的实例时,即指该对象支持类所定义的接口。可参见GOF的
本文标题:面向对象的设计法则系列--BobTarr
链接地址:https://www.777doc.com/doc-1980885 .html