当前位置:网站首页>优先使用对象组合,而不是类继承
优先使用对象组合,而不是类继承
2022-07-05 03:36:00 【跳动的bit】
《极限编程》(Extreme programming)的指导原则之一是“只要能用,就做最简单的”。一个似乎需要继承的设计常常能够戏剧性地使用组合来代替而大简化,从而使其更加灵活。因此,在考虑一个设计时,问问自己:“使用组合是不是更简单?这里真的需要继承吗?它能带来什么好处?”
继承和组合的比较:
面向对象系统中功能复用的两种最常用技术是类继承和对象组合(object composition)。正如我们已解释过的,类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,父类的内部细节对子类可见。
对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。
继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,因为程序设计语言直接支持类继承。类继承可以较方便地改变被复用的实现。当一个子类重定义一些而不是全部操作时,它也能影响它所继承的操作,只要在这些操作中调用了被重定义的操作。
但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了部分子类的具体表示。因为继承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性” 。子类中的实现与它的父类有如此紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,实现上的依赖性就会产生一些问题。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。
对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象一起使用。这还会产生良好的结果:因为对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。
对象组合对系统设计还有另一个作用,即优先使用对象组合有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。另一方面,基于对象组合的设计会有更多的对象 (而有较少的类),且系统的行为将依赖于对象间的关系而不是被定义在某个类中。
这导出了我们的面向对象设计的第二个原则:优先使用对象组合,而不是类继承。
原文链接:https://www.cnblogs.com/nexiyi/archive/2013/06/16/3138568.html
边栏推荐
- v-if VS v-show 2.0
- Kubernetes -- cluster expansion principle
- Unity implements the code of the attacked white flash (including shader)
- ABP vNext microservice architecture detailed tutorial - distributed permission framework (Part 2)
- How rem is used
- [summary of two registration methods]
- [105] Baidu brain map - Online mind mapping tool
- A brief introduction to the behavior tree of unity AI
- In MySQL Association query, the foreign key is null. What if the data cannot be found?
- Nmap使用手册学习记录
猜你喜欢

De debugging (set the main thread as hidden debugging to destroy the debugging Channel & debugger detection)

UE4 DMX和grandMA2 onPC 3.1.2.5的操作流程

Easy processing of ten-year futures and stock market data -- Application of tdengine in Tongxinyuan fund
![[groovy] string (string type variable definition | character type variable definition)](/img/d8/f02e6ad760fb039873718ff7a97b0a.jpg)
[groovy] string (string type variable definition | character type variable definition)

Timing manager based on C #

IPv6 experiment

Why do some programmers change careers before they are 30?
![[2022 repair version] community scanning code into group activity code to drain the complete operation source code / connect the contract free payment interface / promote the normal binding of subordi](/img/ab/e90177c22edc77238250e56c1a0a46.jpg)
[2022 repair version] community scanning code into group activity code to drain the complete operation source code / connect the contract free payment interface / promote the normal binding of subordi

【web审计-源码泄露】获取源码方法,利用工具

Kbp206-asemi rectifier bridge kbp206
随机推荐
[C language] address book - dynamic and static implementation
040. (2.9) relieved
001 chip test
In MySQL Association query, the foreign key is null. What if the data cannot be found?
How can we truncate the float64 type to a specific precision- How can we truncate float64 type to a particular precision?
Operation flow of UE4 DMX and grandma2 onpc 3.1.2.5
有個疑問 flink sql cdc 的話可以設置並行度麼, 並行度大於1會有順序問題吧?
Delphi read / write JSON format
[105] Baidu brain map - Online mind mapping tool
[web source code code code audit method] audit skills and tools
Cette ADB MySQL prend - elle en charge SQL Server?
Solve the problem that sqlyog does not have a schema Designer
Mongodb common commands
DECLARE_ WAIT_ QUEUE_ HEAD、wake_ up_ Interruptible macro analysis
Share the newly released web application development framework based on blazor Technology
Accuracy problem and solution of BigDecimal
[数组]566. 重塑矩阵-简单
Yyds dry goods inventory embedded matrix
【PHP特性-变量覆盖】函数的使用不当、配置不当、代码逻辑漏洞
Containerization Foundation