一些面向对象的设计法则-法则1:优先使用(对象)组合,而非(类)继承

原创 2004年09月20日 19:39:00

法则1:优先使用(对象)组合,而非(类)继承

[ Favor Composition Over Inheritance ]<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

组合

n         (对象)组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。

n         将功能委托给所组合的一个对象,从而获得新功能。

n         有些时候也称之为“聚合”(aggregation)或“包容”(containment),尽管有些作者对这些术语赋予了专门的含义

n         例如:

F        聚合:一个对象拥有另一个对象或对另一个对象负责(即一个对象包含另一个对象或是另一个对象的一部分),并且聚合对象和其所有者具有相同的生命周期。(译者注:即所谓的“同生共死”关系,可参见GOFDesign Patterns: Elements of Reusable Object-Oriented Software的引言部分。)

F        包容:一种特殊类型的组合,对于其它对象而言,容器中的被包含对象是不可见的,其它对象仅能通过容器对象来访问被包含对象。(Coad

 

n         包含可以通过以下两种方式实现:

F        根据引用(By reference

F        根据值(By value

n         C++允许根据值或引用来实现包含。

n         但是在Java中,一切皆为对象的引用!

组合的优点和缺点

n         优点:

F        容器类仅能通过被包含对象的接口来对其进行访问。

F        “黑盒”复用,因为被包含对象的内部细节对外是不可见。

F        对装性好。

F        实现上的相互依赖性比较小。(译者注:被包含对象与容器对象之间的依赖关系比较少)

F        每一个类只专注于一项任务。

F        通过获取指向其它的具有相同类型的对象引用,可以在运行期间动态地定义(对象的)组合。

 

n         缺点:

F        从而导致系统中的对象过多。

F        为了能将多个不同的对象作为组合块(composition block)来使用,必须仔细地对接口进行定义。

继承

n         (类)继承是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。

n         泛化类(超类)可以显式地捕获那些公共的属性和方法。

n         特殊类(子类)则通过附加属性和方法来进行实现的扩展。

继承的优点和缺点

n         优点:

F        容易进行新的实现,因为其大多数可继承而来。

F        易于修改或扩展那些被复用的实现。

n         缺点:

F        破坏了封装性,因为这会将父类的实现细节暴露给子类。

F        “白盒”复用,因为父类的内部细节对于子类而言通常是可见的。

F        当父类的实现更改时,子类也不得不会随之更改。

F        从父类继承来的实现将不能在运行期间进行改变。

Coad规则

仅当下列的所有标准被满足时,方可使用继承:

n         子类表达了“是一个的特殊类型”,而非“是一个由所扮演的角色”。

n         子类的一个实例永远不需要转化(transmute)为其它类的一个对象。

n         子类是对其父类的职责(responsibility)进行扩展,而非重写或废除(nullify)。

n         子类没有对那些仅作为一个工具类(utility class)的功能进行扩展。

n         对于一个位于实际的问题域(Problem Domain)的类而言,其子类特指一种角色(role),交易(transaction)或设备(device)。

继承/组合示例1

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

n         “是一个的特殊类型”,而非“是一个由所扮演的角色”

F        失败。乘客是人所扮演的一种角色。代理人亦然。

n         永远不需要转化

F        失败。随着时间的发展,一个Person的子类实例可能会从Passenger转变成Agent,再到Agent Passenger

n         扩展,而非重写和废除

F        通过。

n         不要扩展一个工具类

F        通过。

n         在问题域内,特指一种角色,交易或设备

F        失败。Person不是一种角色,交易或设备。

继承并非适用于此处!

 

使用组合进行挽救!

继承/组合示例2

n         “是一个的特殊类型”,而非“是一个由所扮演的角色”

F        通过。乘客和代理人都是特殊类型的人所扮演的角色。

n         永远不需要转化

F        通过。一个Passenger对象将保持不变;Agent对象亦然。

n         扩展,而非重写和废除

F        通过。

n         不要扩展一个工具类

F        通过。

n         在问题域内,特指一种角色,交易或设备

F        通过。PersonRole是一种类型的角色。

继承适用于此处!

继承/组合示例3

n         “是一个的特殊类型”,而非“是一个由所扮演的角色”

F        通过。预订和购买都是一种特殊类型的交易。

n         永远不需要转化

F        通过。一个Reservation对象将保持不变;Purchase对象亦然。

n         扩展,而非重写和废除

F        通过。

n         不要扩展一个工具类

F        通过。

n         在问题域内,特指一种角色,交易或设备

F        通过。是一种交易。

继承适用于此处!

继承/组合示例4

n         “是一个的特殊类型”,而非“是一个由所扮演的角色”

F        失败。预订不是一种特殊类型的observable

n         永远不需要转化

F        通过。一个Reservation对象将保持不变。

n         扩展,而非重写和废除

F        通过。

n         不要扩展一个工具类

F        失败。Observable就是一个工具类。

n         在问题域内,特指一种角色,交易或设备

F        不适用。Observable是一个工具类,并非一个问题域的类。。

继承并非适用于此处!

继承/组合总结

n         组合与继承都是重要的重用方法

n         OO开发的早期,继承被过度地使用

n         随着时间的发展,我们发现优先使用组合可以获得重用性与简单性更佳的设计

n         当然可以通过继承,以扩充(enlarge)可用的组合类集(the set of composable classes)。

n         因此组合与继承可以一起工作

n         但是我们的基本法则是:

优先使用对象组合,而非(类)继承
[ Favor Composition Over Inheritance ]

设计模式(笔记)优先使用对象组合而不是类继承

优先使用对象组合而不是类继承 问 概述 继承和组合都能达到一个代码复用的效果,但是类的继承通常是白箱复用,对象组合通常为黑箱复用。我们在使用继承的时候同时也就拥有了父对象中的保护成员,增...
  • liaoqianchuan00
  • liaoqianchuan00
  • 2014年05月01日 12:00
  • 3517

优先使用组合对象,而不是继承"的理解

继承应该不陌生了,OO的基本特性之一,由于继承易于理解,比很多地方都用,可以说有面向对象设计的地方都用,以至于被滥用。组合对象,可能听到的也有,但真正理解的可能就不多了的。笔者刚看到组合对象这词也很蒙...
  • tengzhaorong
  • tengzhaorong
  • 2011年09月06日 18:24
  • 2409

面向对象的设计法则(1)——优先使用(对象)组合,而非(类)继承

[ Favor Composition Over Inheritance ]  组合  1.(对象)组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。  2.将功能委托给所组合的一...
  • xiaoyu411502
  • xiaoyu411502
  • 2008年12月27日 19:50
  • 591

面向对象设计原则七 - 组合优先于继承

组合通过创建一个由其他对象组合的对象来获得新功能的重用方法新功能的获得是通过调用组合对象的功能实现的有时又叫聚合例如: 一个对象拥有或者对另外一个对象负责并且两个对象有相同的生命周期。(GOF)一个对...
  • zjliu1984
  • zjliu1984
  • 2009年06月26日 09:31
  • 5635

[阅读笔记]面向对象的设计法则--法则1:优先使用(对象)组合,而非(类)继承 Favor Composition Over Inheritance

组合      组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。      将功能委托给所组合的一个对象,从而获得新功能。      实现方式   根据引用(By referen...
  • Starsiday
  • Starsiday
  • 2006年10月03日 17:00
  • 1140

Bob Tarr:一些面向对象的设计法则(3):Program To An Interface, Not An Implementation

法则2:针对接口编程,而非(接口的)实现 [ Program To An Interface, Not An Implementation ] 接口 1.接口是一个对象在对其...
  • bookjohn
  • bookjohn
  • 2007年05月10日 18:17
  • 937

为什么要优先使用组合 而不是继承?

继承具有如下优点:        实现新的类非常容易,因为基类的大部分功能都可以通过继承关系自动赋予派生类;修改或者扩展继承来的实现非常容易;只要修改父类,派生的类的行为就同时被修改了。初学面向对象...
  • wangjiangang_
  • wangjiangang_
  • 2015年05月25日 11:27
  • 1135

一些面向对象的设计法则(1)

法则1:优先使用(对象)组合,而非(类)继承[ Favor Composition Over Inheritance ] 组合 1.(对象)组合是一种通过创建一个组合了其它...
  • cthlcm
  • cthlcm
  • 2006年10月09日 01:52
  • 450

一些面向对象的设计法则(1)

法则1:优先使用(对象)组合,而非(类)继承    [ Favor Composition Over Inheritance ]     组合    1.(对象)组合是一种通过创建一个组合了其它对象的...
  • wangyongligood
  • wangyongligood
  • 2007年10月23日 23:47
  • 217

一些面向对象的设计法则(1)

google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";...
  • java169
  • java169
  • 2008年05月23日 22:21
  • 148
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一些面向对象的设计法则-法则1:优先使用(对象)组合,而非(类)继承
举报原因:
原因补充:

(最多只允许输入30个字)