面向对象的设计原则(JAVA)

一、单一职责原则(Single Responsibility Principe,SRP

1.1单一职责原则的定义

1)定义:在软件系统中,一个类只负责一个功能领域中的相应职责。

2)另一种定义方式如下:就一个类而言,应该仅有一个引起它变化的原因。

1.2对可变性的封装原则

一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小。而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。

类的职责主要包过两方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。

单一职责原则是实现高内聚、低耦合的指导方针,在很多代码重构手法中都能找到它的存在,它是最简单又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。

二、开闭原则(Open-Closed Principle,OCP

      2.1开闭原则的定义

      一个软件实体应当对扩展开放,对修改关闭。也就是说在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。

      2.2开闭原则分析

      在开闭原则的定义中,软件实体可以指一个软件模块,一个由多个类组成的局部结构或一个独立的类。

抽象化是开闭原则的关键。

绝大部分的设计模块都符合开闭原则,在对每一个模式进行优缺点评价时都会以开闭原则作为一个重要的评价依据,以判断基于该模式设计的系统是否具备良好的灵活性和可扩展性。

三、里氏代换原则(Liskov Substitution Principle,LSP

      3.1里氏代换原则定义

      1)如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有变化,那么类型S是类型T的子类。

2)所有引用基类(父类)的地方必须能透明地使用其子类的对象。

  3.2里氏代换原则分析

      里氏代换原则可以通俗表述为:在软件中如果能使用基类对象,那么一定能够使用其子类对象。把基类都替换成它的子类,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类的话,那么它不一定能够使用基类。

里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

四、依赖倒转原则dependenceinversion principle, DIP

    4.1概念

依赖倒转原则就是要依赖于抽象,不要依赖于实现。(Abstractionsshould not depend upon details. Details should depend uponabstractions.)要针对接口编程,不要针对实现编程。(Program to aninterface, not an implementation.)

也就是说应当使用接口和抽象类进行变量类型声明、参数类型声明、方法返还类型说明,以及数据类型的转换等。而不要用具体类进行变量的类型声明、参数类型声明、方法返还类型说明,以及数据类型的转换等。要保证做到这一点,一个具体类应当只实现接口和抽象类中声明过的方法,而不要给出多余的方法。

传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块,抽象层次依赖于具体层次。倒转原则就是把这个错误的依赖关系倒转过来。

面向对象设计的重要原则是创建抽象化,并且从抽象化导出具体化,具体化给出不同的实现。继承关系就是一种从抽象化到具体化的导出。

抽象层包含的应该是应用系统的商务逻辑和宏观的、对整个系统来说重要的战略性决定,是必然性的体现。具体层次含有的是一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有相当大的偶然性选择。具体层次的代码是经常变动的,不能避免出现错误。

从复用的角度来说,高层次的模块是应当复用的,而且是复用的重点,因为它含有一个应用系统最重要的宏观商务逻辑,是较为稳定的。而在传统的过程性设计中,复用则侧重于具体层次模块的复用。

依赖倒转原则则是对传统的过程性设计方法的“倒转”,是高层次模块复用及其可维护性的有效规范。

特例:对象的创建过程是违背“开—闭”原则以及依赖倒转原则的,但通过工厂模式,能很好地解决对象创建过程中的依赖倒转问题。

4.2关系

“开-闭”原则与依赖倒转原则是目标和手段的关系。如果说开闭原则是目标,依赖倒转原则是到达"开闭"原则的手段。如果要达到最好的"开闭"原则,就要尽量的遵守依赖倒转原则,依赖倒转原则是对"抽象化"的最好规范。

里氏代换原则是依赖倒转原则的基础,依赖倒转原则是里氏代换原则的重要补充。

4.3耦合(或者依赖)关系的种类:

零耦合(NilCoupling)关系:两个类没有耦合关系

具体耦合(ConcreteCoupling)关系:发生在两个具体的(可实例化的)类之间,经由一个类对另一个具体类的直接引用造成。

抽象耦合(AbstractCoupling)关系:发生在一个具体类和一个抽象类(或接口)之间,使两个必须发生关系的类之间存有最大的灵活性。

五、接口隔离原则(Interface Segregation Principle,ISP

      5.1接口隔离原则定义

      1)客户端不应该依赖那些它不需要的接口

2)一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。

5.2接口隔离原则分析

      接口隔离原则是指使用多个专门的接口,而不使用单一的总接口。每一个接口应该承担一种相对独立的角色,不多不少,不干不该干的事,该干的事都要干。

(1)一个接口就只代表一个角色,每个角色都有它特定的一个接口,此时这个原则可以叫做“角色隔离原则”。

(2)接口仅仅提供客户端需要的行为。即所需的方法,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。

使用接口隔离原则拆分接口时,首先必须满足单一职责原则,将一组相关的操作定义在一个接口中,且在满足高内聚的前提下,接口中的方法越少越好。

可以在进行系统设计时采用定制服务的方式,即为不同的客户端提供宽窄不同的接口,只提供用户需要的行为,而隐藏用户不需要的行为。

六、合成/聚合复用原则(Composite/AggregateReusePrincipleCARP

    6.1概念

定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的。

应首先使用合成/聚合,合成/聚合则使系统灵活,其次才考虑继承,达到复用的目的。而使用继承时,要严格遵循里氏代换原则。有效地使用继承会有助于对问题的理解,降低复杂度,而滥用继承会增加系统构建、维护时的难度及系统的复杂度。

如果两个类是“Has-a”关系应使用合成、聚合,如果是“Is-a”关系可使用继承。"Is-A"是严格的分类学意义上定义,意思是一个类是另一个类的"一种"。而"Has-A"则不同,它表示某一个角色具有某一项责任。

6.2什么是合成?什么是聚合?

合成(Composition)和聚合(Aggregation)都是关联(Association)的特殊种类。

聚合表示整体和部分的关系,表示“拥有”。如奔驰S360汽车,对奔驰S360引擎、奔驰S360轮胎的关系是聚合关系,离开了奔驰S360汽车,引擎、轮胎就失去了存在的意义。在设计中,聚合不应该频繁出现,这样会增大设计的耦合度。

合成则是一种更强的“拥有”,部分和整体的生命周期一样。合成的新的对象完全支配其组成部分,包括它们的创建和湮灭等。一个合成关系的成分对象是不能与另一个合成关系共享的。

换句话说,合成是值的聚合(Aggregation byValue),而一般说的聚合是引用的聚合(Aggregation byReference)。

明白了合成和聚合关系,再来理解合成/聚合原则应该就清楚了,要避免在系统设计中出现,一个类的继承层次超过3层,则需考虑重构代码,或者重新设计结构。当然最好的办法就是考虑使用合成/聚合原则。

6.3通过合成/聚合的优缺点

优点:

1)新对象存取成分对象的唯一方法是通过成分对象的接口。

2)这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。

3) 这种复用支持包装。

4) 这种复用所需的依赖较少。

5)每一个新的类可以将焦点集中在一个任务上。

6)这种复用可以在运行时间内动态进行,新对象可以动态的引用与成分对象类型相同的对象。

7)作为复用手段可以应用到几乎任何环境中去。

缺点:就是系统中会有较多的对象需要管理。

6.4通过继承来进行复用的优缺点

优点:

新的实现较为容易,因为超类的大部分功能可以通过继承的关系自动进入子类。

修改和扩展继承而来的实现较为容易。

缺点

继承复用破坏包装,因为继承将超类的实现细节暴露给子类。由于超类的内部细节常常是对于子类透明的,所以这种复用是透明的复用,又称“白箱”复用。

如果超类发生改变,那么子类的实现也不得不发生改变。

从超类继承而来的实现是静态的,不可能在运行时间内发生改变,没有足够的灵活性。

继承只能在有限的环境中使用。

七、 迪米特法则(Lawof DemeterLoD

    7.1迪米特法则定义

定义:一个软件实体应当尽可能少的与其他实体发生相互作用。

这样,当一个模块修改时,就会尽量少的影响其他的模块。扩展会相对容易。

这是对软件实体之间通信的限制。它要求限制软件实体之间通信的宽度和深度。

7.2迪米特法则的其他表述:

1)只与你直接的朋友们通信。

2)不要跟“陌生人”说话。

3)每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

7.3狭义的迪米特法则

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

朋友圈的确定

“朋友”条件:

1)当前对象本身(this)

2)以参量形式传入到当前对象方法中的对象

3)当前对象的实例变量直接引用的对象

4)当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友

5)当前对象所创建的对象

任何一个对象,如果满足上面的条件之一,就是当前对象的“朋友”;否则就是“陌生人”。

缺点:会在系统里造出大量的小方法,散落在系统的各个角落。

与依赖倒转原则互补使用

7.4狭义的迪米特法则的缺点:

在系统里造出大量的小方法,这些方法仅仅是传递间接的调用,与系统的商务逻辑无关。

遵循类之间的迪米特法则会是一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有直接的关联。但是,这也会造成系统的不同模块之间的通信效率降低,也会使系统的不同模块之间不容易协调。

7.5广义的迪米特法则

指对对象之间的信息流量,流向以及信息的影响的控制,主要是对信息隐藏的控制。信息的隐藏可以使各个子系统之间脱耦,从而允许它们独立地被开发,优化、使用和修改,同时可以促进软件的复用,由于每一个模块都不依赖于其他模块而存在,因此每一块模块都可以独立地在其他的地方使用。一个系统的规模越大,信息的隐藏就越重要,而信息隐藏的重要性也就越明显。

摘自于:http://www.cnblogs.com/hulitut/archive/2012/03/22/2412668.html

时间: 2024-10-11 13:32:15

面向对象的设计原则(JAVA)的相关文章

java 28 - 1 设计模式 之 面向对象思想设计原则和模版设计模式概述

在之前的java 23 中,了解过设计模式的单例模式和工厂模式.在这里,介绍下设计模式 面向对象思想设计原则 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计原则 单一职责原则 开闭原则 里氏替换原则 依赖注入原则 接口分离原则 迪米特原则 单一职责原则 其实就是开发人员经常说的"高内聚,低耦合" 也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个.在设计模式中,所有的设计模式都遵循这一原则. 开闭原则 核

Java 面向对象的设计原则

一. 1.面向对象思想的核心: 封装.继承.多态.   2.面向对象编程的追求: 高内聚低耦合的解决方案: 代码的模块化设计: 3.什么是设计模式: 针对反复出现的问题的经典解决方案,是对特定条件下(上下文)问题的设计方案的经验总结,是前人设计实践经验的精华. 4.面向对象设计原则 是面向对象设计思想(法理精神)的提炼(基本宪法),比面向对象思想的核心要素更具有实操性,比设计模式(各种具体法律条文)更抽象. 5.如何最大限度降低耦合度? 少用类的继承,多用接口隐藏实现细节. 避免使用全局变量.

GOF 的23种JAVA常用设计模式总结 03 面向对象七大设计原则

在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据 7 条原则来开发程序,从而提高软件开发效率.节约软件开发成本和维护成本. 各位代码界的大佬们总结出的七大设计原则,还是需要好好了解一下 1.开闭原则 开闭原则(Open Closed Principle,OCP)由勃兰特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作<面向对象软件构造>(Object Oriented Software Construction)中提出:软件实

面向对象的设计原则

面向对象设计原则是学习设计模式的基础,每一种设计模式都符合某一种或者多种面向对象设计原则.通过在软件开发中使用这些原则可以提高软件的可维护行和可用性,让我们可以设计出更加灵活也更加容易扩展的软件系统,实现可维护可复用的目标.在使用面向对象的思想进行系统设计时,前人共总结出了7条原则,它们分别是:单一职责原则.开闭原则.里氏替换原则.依赖注入原则.接口分离原则.迪米特原则和合成复用原则. 1.单一职责原则(SRP) 单一职责原则的核心思想就是:系统中的每一个对象都应该只有一个单独的职责,而所有对象

面向对象思想设计原则 及常见设计模式

1.面向对象思想设计原则 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计原则. 1)单一职责原则:就是开发人员经常说的”高内聚,低耦合”.也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个.在设计模式中,所有的设计模式都遵循这一原则. 2)开闭原则:一个对象对扩展开放,对修改关闭.也就是说,对类的改动是通过增加代码进行的,而不是修改现有代码.软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直

零散知识点(面向对象七大设计原则,jdbc--BaseDao,jsp九大内置对象。四个作用域)

面向对象七大设计原则: 1.开闭原则(OCP:Open-Closed Principle)2.里氏替换原则(LSP:Liskov Substitution Principle) 3.单一职责原则(SRP:Single responsibility principle)4.接口隔离原则(ISP:Interface Segregation Principle)5.依赖倒置原则(DIP:Dependence Inversion Principle)6.迪米特法则(LOD:Law of Demeter)

【设计模式】 面向对象六大设计原则

面向对象设计的六大原则 : 单一职责原则, 里氏替换原则, 依赖倒置原则, 接口隔离原则, 迪米特法则, 开闭原则; 一. 单一职责原则 1. 单一职责简介 单一职责定义 : 有且只有一个原因引起类的变化, 一个接口 或者 类 只有一个职责; 单一职责的好处 : -- 复杂性 : 降低类的复杂性, 对类或接口的职责有清晰明确定义; -- 可读性 : 提高可读性; -- 维护 : 提高可维护性; -- 变更风险 : 降低变更引起的风险, 接口改变只影响相应的实现类, 不影响其他类; 2. 单一职责

面向对象软件设计原则

提起面向对象,大家也许觉得自己已经非常“精通”了,起码也到了“灵活运用”的境界.面向对象设计不就是OOD吗?不就是用C++.Java.Smalltalk等面向对象语言写程序吗?不就是封装+继承+多态吗? 很好!大家已经掌握了不少对面向对象设计的基本要素:开发语言.基本概念.机制.Java是一种纯面向对象语言,是不是用Java写程序就等于面向对象了呢?我先列举一下面向对象设计的11个原则,测试一下大家对面向对象设计的理解程度-^_^- 单一职责原则(The Single Responsibilit

喵星之旅-沉睡的猫咪-面向对象的设计原则

一.设计原则是什么? 有句话叫“人民群众是历史的创造者”,他的意思我理解为任何的理论都是基于具体的客观展现总结出来的,没有人民创造的既定事实,就无法出现任何的有理有据的理论模型. 对于面向对象的软件设计,最著名的一本书就应该是当年gof的那一本<设计模式:可复用面向对象软件的基础>.设计模式是面对具体问题,进行抽象分类,然后总结出来的行之有效的解决方案,就像人去创造历史.设计原则是进一步研究这些解决方案,进一步抽象出的指导思想. 如果把设计模式比喻成传统数学,即“1+1=2”的那套理论,那么设

第2章 面向对象的设计原则(SOLID):3_依赖倒置原则

3. 依赖倒置原则(Dependence Inversion Principle,DIP) 3.1 定义 (1)要依赖抽象,不要依赖具体的实现类.简单的说就是对抽象(或接口)进行编程,不要依赖实现进行编程,这样就降低了客户与实现模块间的耦合.包含3层含义: ①高层模块不应依赖低层模块,两者都应该依赖于抽象 ②抽象不应该依赖细节 ③细节应该依赖于抽象 (2)何为“高层模块”和“低层模块” ①“低层模块”:每个逻辑的实现都是原子逻辑组成,不可分割的原子逻辑就是低层模块.一般和具体实现相关. ②“高层