oop设计原则

本文介绍了面向对象设计中的四大基本原则:开闭原则、里氏代换原则、依赖倒转原则及迪米特原则。开闭原则强调软件实体应当对扩展开放,对修改关闭;里氏代换原则确保基类和子类之间的正确替换;依赖倒转原则提倡依赖于抽象而非具体实现;迪米特原则旨在降低类间的耦合度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 开闭原则

1 什么是开闭原则

  开闭原则是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。

  1988年,Bertrand Meyer在他的著作《Object Oriented Software Construction》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。这句话说得略微有点专业,我们把它讲得更通俗一点,也就是:软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。

  2 如何实现开闭原则

  实现开闭原则的关键就在于“抽象”。把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规定出所有的具体实现必须提供的方法的特征。作为系统设计的抽象层,要预见所有可能的扩展,从而使得在任何扩展情况下,系统的抽象底层不需修改;同时,由于可以从抽象底层导出一个或多个新的具体实现,可以改变系统的行为,因此系统设计对扩展是开放的。

  我们在软件开发的过程中,一直都是提倡需求导向的。这就要求我们在设计的时候,要非常清楚地了解用户需求,判断需求中包含的可能的变化,从而明确在什么情况下使用开闭原则。

3 开闭原则能够带来什么好处

  如果一个软件系统符合开闭原则的,那么从软件工程的角度来看,它至少具有这样的好处:

  可复用性好。

  我们可以在软件完成以后,仍然可以对软件进行扩展,加入新的功能,非常灵活。因此,这个软件系统就可以通过不断地增加新的组件,来满足不断变化的需求。

  可维护性好。

  由于对于已有的软件系统的组件,特别是它的抽象底层不去修改,因此,我们不用担心软件系统中原有组件的稳定性,这就使变化中的软件系统有一定的稳定性和延续性。 

 

二 里氏代换原则

面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化。这个导出要使用继承关系和一个原则:里氏代换原则(Liskov Substitution Principle LSP)。
     那么什么是里氏代换原则呢?有个严格的表述,绕口,不好记。还是比较白话的这个好记。说的是:一个软件实体如果使用的是一个基类的话那么一定适用于其子类,而且它察觉不出基类对象和子类对象的区别。也就是说,在软件里面,把基类都替换成它的子类,程序的行为没有变化。

三 依赖倒转原则

抽象不应该依赖于细节,细节应当依赖于抽象。

  要针对接口编程,而不是针对实现编程。

  传递参数,或者在组合聚合关系中,尽量引用层次高的类。

  主要是在构造对象时可以动态的创建各种具体对象,当然如果一些具体类比较稳定,就不必再弄一个抽象类做它的父类,这样有画舌添足的感觉

依赖倒转原则
☆ 依赖倒转原则,要依赖于抽象,而不要依赖于具体实现。

ξ 8.3 依赖倒转原则

☆ 三种耦合关系
① 零耦合关系,如果两个类没有耦合关系,就称之为零耦合;
② 具体耦合,具体耦合发生在两个具体的类之间,经由一个类对另外一个具体类的直接引用造成的。
③ 抽象耦合关系,抽象耦合关系发生在一个具体类和一个抽象类之间,使用两个必须发生关系的类之间存在有最大的灵活性。

☆ 依赖倒转原则的另外一种表述是:
要针对接口编程,不要针对实现编程(Program to an interface, not an implementation)[GOF95]。同样,在处理类之间的耦合关系时,尽量使用抽象耦合的形式。
下图中左侧A和B为具体依赖关系,重构后如右图所示,变为抽象依赖:


☆ 里氏替换原则是依赖倒转原则的基础。

☆ 工厂模式、模板模式、迭代子模式都是对依赖倒转原则的体现。

 

四 迪米特原则
迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文简写为: LoD.

  迪米特法则可以简单说成:talk only to your immediate friends。 对于面向OOD来说,又被解释为下面几种方式:一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

  迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。  迪米特法则不希望类直接建立直接的接触。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。  有兴趣可以研究一下设计模式的门面模式(Facade)和中介模式(Mediator),都是迪米特法则应用的例子。  值得一提的是,虽然Ian Holland对计算机科学的贡献也仅限于这一条法则,其他方面的建树不多,但是,这一法则却不仅仅局限于计算机领域,在其他领域也同样适用。比如,美国人就在航天系统的设计中采用这一法则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值