软件设计七大原则

正如牛顿三大定律在经典力学中的位置同样,“开-闭”原则(Open-Closed Principle)是面向对象的可复用设计(Object Oriented Design或OOD)的基石。其余设计原则(里氏代换原则、依赖倒转原则、合成/聚合复用原则、迪米特法则、接口隔离原则)是实现“开-闭”原则的手段和工具。html

一.开-闭原则(Open-Closed Principle, OCP)程序员

1.什么是开闭原则算法

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

2.如何实现开闭原则c#

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

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

关于系统可变的部分,还有一个更具体的原则是可变性的封装原则(Principle of Encapsulation of Variation,  EVP),它从软件工程实现的角度对开闭原则进行了进一步的解释。EVP要求在作系统设计的时候,对系统全部可能发生变化的部分进行评估和分类,每个可变的因素都单独进行封装。“对可变性的封装原则”意味着两点:函数

(1)一种可变性不该当散落在代码的不少角落里,而应当被封装到一个对象里面。同一种可变性的不一样表象意味着同一个继承等级结构中的具体子类,所以,咱们能够期待在设计模式中看到继承关系。继承应当被看作是封装变化的方法,而不该当被认为是从通常的对象生成特殊的对象的方法。工具

(2)一种可变性不该当与另外一种可变性混合在一块儿。测试

咱们在实际开发过程的设计开始阶段,就要罗列出来系统全部可能的行为,并把这些行为加入到抽象底层,根本就是不可能的,这么去作也是不经济的,费时费力。另外,在设计开始阶段,对全部的可变因素进行预计和封装也不太现实,也是很难作获得。因此,开闭原则描绘的愿景只是一种理想状况或是极端状态,现实世界中是很难被彻底实现的。咱们只能在某些组件,在某种程度上符合开闭原则的要求。

经过以上的分析,对于开闭原则,咱们能够得出这样的结论:虽然咱们不可能作到百分之百的封闭,可是在系统设计的时候,咱们仍是要尽可能作到这一点。

对于软件系统的功能扩展,咱们能够经过继承、重载或者委托等手段实现。以接口为例,它对修改就是是封闭的,而对具体的实现是开放的,咱们能够根据实际的须要提供不一样的实现,因此接口是符合开闭原则的。

3.开闭原则可以带来什么好处

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

(1)可复用性好

咱们能够在软件完成之后,仍然能够对软件进行扩展,加入新的功能,很是灵活。所以,这个软件系统就能够经过不断地增长新的组件,来知足不断变化的需求。

(2)可维护性好

因为对于已有的软件系统的组件,特别是它的抽象底层不去修改,所以,咱们不用担忧软件系统中原有组件的稳定性,这就使变化中的软件系统有必定的稳定性和延续性。

4.闭原则与其它原则的关系

开闭原则具备理想主义的色彩,它是面向对象设计的终极目标。所以,针对开闭原则的实现方法,一直都有面向对象设计的大师费尽心机,研究开闭原则的实现方式。其它原则和方法如:里氏代换原则(LSP)、依赖倒转原则(DIP)、接口隔离原则(ISP)以及抽象类(Abstract Class)、接口(Interace)等等,均可以看做是开闭原则的实现方法。

此部分参考:http://www.cnblogs.com/wanghao72214/archive/2009/03/13/1410610.html

二.里氏代换原则(Liskov Substitution Principle,LSP)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类能够出现的地方,子类必定能够出现。 LSP是继承复用的基石,只有当衍生类能够替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也可以在基类的基础上增长新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,因此里氏代换原则是对实现抽象化的具体步骤的规范。

LSP讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。若是两个具体的类A,B之间的关系违反了LSP的设计,(假设是从B到A的继承关系)那么根据具体的状况能够在下面的两种重构方案中选择一种。

-----建立一个新的抽象类C,做为两个具体类的超类,将A,B的共同行为移动到C中来解决问题。

-----从B到A的继承关系改成委派关系。

为了说明,咱们先用第一种方法来看一个例子,第二种办法在另一个原则中说明。咱们就看那个著名的长方形和正方形的例子。对于长方形的类,若是它的长宽相等,那么它就是一个正方形,所以,长方形类的对象中有一些正方形的对象。对于一个正方形的类,它的方法有个setSide和getSide,它不是长方形的子类,和长方形也不会符合LSP。

eg:

长方形类:

public class Rectangle{

...

setWidth(int width){

this.width=width;

}

setHeight(int height){

this.height=height

}

}

正方形类:

public class Square{

...

setWidth(int width){

this.width=width;

this. height=width;

}

setHeight(int height){

this.setWidth(height);

}

}

例子中改变边长的函数:

public void resize(Rectangle r){

while(r.getHeight()<r.getWidth){

r.setHeight(r.getWidth+1);

}

}

那么,若是让正方形当作是长方形的子类,会出现什么状况呢?咱们让正方形从长方形继承,而后在它的内部设置width等于height,这样,只要width或者height被赋值,那么width和height会被同时赋值,这样就保证了正方形类中,width和height老是相等的.如今咱们假设有个客户类,其中有个方法,规则是这样的,测试传入的长方形的宽度是否大于高度,若是知足就中止下来,不然就增长宽度的值。如今咱们来看,若是传入的是基类长方形,这个运行的很好。根据LSP,咱们把基类替换成它的子类,结果应该也是同样的,可是由于正方形类的width和height会同时赋值,这个方法没有结束的时候,条件老是不知足,也就是说,替换成子类后,程序的行为发生了变化,它不知足LSP。

那么咱们用第一种方案进行重构,咱们构造一个抽象的四边形类,把长方形和正方形共同的行为放到这个四边形类里面,让长方形和正方形都是它的子类,问题就OK了。对于长方形和正方形,取width和height是它们共同的行为,可是给width和height赋值,二者行为不一样,所以,这个抽象的四边形的类只有取值方法,没有赋值方法。上面的例子中那个方法只会适用于不一样的子类,LSP也就不会被破坏。

在进行设计的时候,咱们尽可能从抽象类继承,而不是从具体类继承。若是从继承等级树来看,全部叶子节点应当是具体类,而全部的树枝节点应当是抽象类或者接口。固然这个只是一个通常性的指导原则,使用的时候还要具体状况具体分析。

三.依赖倒置原则(Dependence Inversion Principle,DIP)

1.概念

依赖倒转原则就是要依赖于抽象,不要依赖于实现。(Abstractions should not depend upon details. Details should depend upon abstractions.)要针对接口编程,不要针对实现编程。(Program to an interface, not an implementation.)也就是说应当使用接口和抽象类进行变量类型声明、参数类型声明、方法返还类型说明,以及数据类型的转换等。而不要用具体类进行变量的类型声明、参数类型声明、方法返还类型说明,以及数据类型的转换等。要保证作到这一点,一个具体类应当只实现接口和抽象类中声明过的方法,而不要给出多余的方法。 
传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块,抽象层次依赖于具体层次。倒转原则就是把这个错误的依赖关系倒转过来。面向对象设计的重要原则是建立抽象化,而且从抽象化导出具体化,具体化给出不一样的实现。继承关系就是一种从抽象化到具体化的导出。抽象层包含的应该是应用系统的商务逻辑和宏观的、对整个系统来讲重要的战略性决定,是必然性的体现。具体层次含有的是一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有至关大的偶然性选择。具体层次的代码是常常变更的,不能避免出现错误。 
从复用的角度来讲,高层次的模块是应当复用的,并且是复用的重点,由于它含有一个应用系统最重要的宏观商务逻辑,是较为稳定的。而在传统的过程性设计中,复用则侧重于具体层次模块的复用。依赖倒转原则则是对传统的过程性设计方法的“倒转”,是高层次模块复用及其可维护性的有效规范。 
特例:对象的建立过程是违背“开—闭”原则以及依赖倒转原则的,但经过工厂模式,能很好地解决对象建立过程当中的依赖倒转问题。

2.关系

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

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

3.耦合(依赖)关系的种类

零耦合(Nil Coupling)关系:两个类没有耦合关系 
具体耦合(Concrete Coupling)关系:发生在两个具体的(可实例化的)类之间,经由一个类对另外一个具体类的直接引用形成。 
抽象耦合(Abstract Coupling)关系:发生在一个具体类和一个抽象类(或接口)之间,使两个必须发生关系的类之间存有最大的灵活性。

3.1如何把握耦合

咱们应该尽量的避免实现继承,缘由以下: 
1 失去灵活性,使用具体类会给底层的修改带来麻烦。 
2 耦合问题,耦合是指两个实体相互依赖于对方的一个量度。程序员天天都在(有意识地或者无心识地)作出影响耦合的决定:类耦合、API耦合、应用程序耦合等等。在一个用扩展的继承实现系统中,派生类是很是紧密的与基类耦合,并且这种紧密的链接多是被不指望的。如B extends A ,当B不全用A中的全部methods时,这时候,B调用的方法可能会产生错误! 
咱们必须客观的评价耦合度,系统之间不可能老是松耦合的,那样确定什么也作不了。

3.2咱们决定耦合程度的依据是什么

简单的说,就是根据需求的稳定性,来决定耦合的程度。对于稳定性高的需求,不容易发生变化的需求,咱们彻底能够把各种设计成紧耦合的(咱们虽然讨论类之间的耦合度,但其实功能块、模块、包之间的耦合度也是同样的),由于这样能够提升效率,并且咱们还可使用一些更好的技术来提升效率或简化代码,例如c# 中的内部类技术。但是,若是需求极有可能变化,咱们就须要充分的考虑类之间的耦合问题,咱们能够想出各类各样的办法来下降耦合程度,可是概括起来,不外乎增长抽象的层次来隔离不一样的类,这个抽象层次能够是抽象的类、具体的类,也能够是接口,或是一组的类。咱们能够用一句话来归纳下降耦合度的思想:"针对接口编程,而不是针对实现编程。 
在咱们进行编码的时候,都会留下咱们的指纹,如public的多少,代码的格式等等。咱们能够耦合度量评估从新构建代码的风险。由于从新构建其实是维护编码的一种形式,维护中遇到的那些麻烦事在从新构建时一样会遇到。咱们知道在从新构建以后,最多见的随机bug大部分都是不当耦合形成的 。 
若是不稳定因素越大,它的耦合度也就越大。 
某类的不稳定因素=依赖的类个数/被依赖的类个数 
依赖的类个数= 在编译此类的时被编译的其它类的个数总和

3.3怎样将大系统拆分红效系统

解决这个问题的一个思路是将许多类集合成一个更高层次的单位,造成一个高内聚、低耦合的类的集合,这是咱们设计过程当中应该着重考虑的问题! 
耦合的目标是维护依赖的单向性,有时咱们也会须要使用坏的耦合。在这种状况下,应当当心记录下缘由,以帮助往后该代码的用户了解使用耦合真正的缘由。

4.怎样作到依赖倒转

以抽象方式耦合是依赖倒转原则的关键。抽象耦合关系总要涉及具体类从抽象类继承,而且须要保证在任何引用到基类的地方均可以改换成其子类,所以,里氏代换原则是依赖倒转原则的基础。 
在抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性,若是一个具体类发生变化的可能性很是小,那么抽象耦合能发挥的好处便十分有限,这时能够用具体耦合反而会更好。 
层次化:全部结构良好的面向对象构架都具备清晰的层次定义,每一个层次经过一个定义良好的、受控的接口向外提供一组内聚的服务。 
依赖于抽象:建议不依赖于具体类,即程序中全部的依赖关系都应该终止于抽象类或者接口。尽可能作到: 
一、任何变量都不该该持有一个指向具体类的指针或者引用。 
二、任何类都不该该从具体类派生。 
三、任何方法都不该该覆写它的任何基类中的已经实现的方法。

5.依赖倒转原则的优缺点

依赖倒转原则虽然很强大,但却最不容易实现。由于依赖倒转的缘故,对象的建立极可能要使用对象工厂,以免对具体类的直接引用,此原则的使用可能还会致使产生大量的类,对不熟悉面向对象技术的工程师来讲,维护这样的系统须要较好地理解面向对象设计。

依赖倒转原则假定全部的具体类都是会变化的,这也不老是正确。有一些具体类多是至关稳定,不会变化的,使用这个具体类实例的应用彻底能够依赖于这个具体类型,而没必要为此建立一个抽象类型。

此部分引用自:http://www.cnblogs.com/temptation/archive/2008/03/10/1098351.html

四.接口隔离原则(Interface Segregation Principle, ISP)

在讲接口隔离原则以前,先明确一下咱们的主角——接口。接口分为两种:

◇ 实例接口(Object Interface),在Java中声明一个类,而后用new关键字产生的一个实例,它是对一个类型的事物的描述,这是一种接口,好比你定义Person这个类,而后使用Person zhangSan = new Person()产生了一个实例,这个实例要听从的标准就是Person这个类,Person类就是zhangSan的接口,疑惑?看不懂?没关系,那是由于让Java语言浸染的时间太长了,只要知道从这个角度来看,Java中的类也是一种接口;  
◇ 类接口(Class Interface),Java中常用的interface关键字定义的接口。  
        主角已经定义清楚了,那什么是隔离呢?它有两种定义,以下所示:  
◇ “Clients should not be forced to depend upon interfaces that they don't use”——客户端不该该依赖它不需用的接口。  
◇ “The dependency of one class to another one should depend on the smallest possible interface”——类间的依赖关系应该创建在最小的接口上。  
        新事物的定义通常都比较难理解,晦涩难懂是正常的。咱们把这两个定义剖析一下,先说第一种定义:“客户端不该该依赖它不须要接口”,那依赖什么?依赖它须要的接口,客户端须要什么接口就提供什么接口,把不须要的接口剔除掉,那就须要对接口进行细化,保证其纯洁性;再看第二个定义:“类间的依赖关系应该创建在最小的接口上”,它要求是最小的接口,也是要求接口细化,接口纯洁,与第一个定义一模一样,只是一个事物的两种不一样描述。  
       咱们能够把这两个定义归纳为一句话:创建单一接口,不要创建臃肿庞大的接口。再通俗一点讲:接口尽可能细化,同时接口中的方法尽可能少。看到这里你们有可能要疑惑了,这与单一职责原则不是相同的吗?错,接口隔离原则与单一职责的审视角度是不相同的,单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划分,而接口隔离原则要求接口的方法尽可能少。例如一个接口的职责可能包含10个方法,这10个方法都放在一个接口中,而且提供给多个模块访问,各个模块按照规定的权限来访问,在系统外经过文档约束“不使用的方法不要访问”,按照单一职责原则是容许的,按照接口隔离原则是不容许的,由于它要求“尽可能使用多个专门的接口”,专门的接口指什么?就是指提供给每一个模块都应该是单一接口,提供给几个模块就应该有几个接口,而不是创建一个庞大的臃肿的接口,容纳全部的客户端访问。

五.合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)

5.1 概念

定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象经过向这些对象的委派达到复用这些对象的目的。应首先使用合成/聚合,合成/聚合则使系统灵活,其次才考虑继承,达到复用的目的。而使用继承时,要严格遵循里氏代换原则。有效地使用继承会有助于对问题的理解,下降复杂度,而滥用继承会增长系统构建、维护时的难度及系统的复杂度。 
若是两个类是“Has-a”关系应使用合成、聚合,若是是“Is-a”关系可以使用继承。"Is-A"是严格的分类学意义上定义,意思是一个类是另外一个类的"一种"。而"Has-A"则不一样,它表示某一个角色具备某一项责任。

5.2 什么是合成?什么是聚合?

合成(Composition)和聚合(Aggregation)都是关联(Association)的特殊种类。 
聚合表示总体和部分的关系,表示“拥有”。如奔驰S360汽车,对奔驰S360引擎、奔驰S360轮胎的关系是聚合关系,离开了奔驰S360汽车,引擎、轮胎就失去了存在的意义。在设计中, 聚合不该该频繁出现,这样会增大设计的耦合度。 
合成则是一种更强的“拥有”,部分和总体的生命周期同样。合成的新的对象彻底支配其组成部分,包括它们的建立和湮灭等。一个合成关系的成分对象是不能与另外一个合成关系共享的。 
换句话说,合成是值的聚合(Aggregation by Value),而通常说的聚合是引用的聚合(Aggregation by Reference)。 
明白了合成和聚合关系,再来理解合成/聚合原则应该就清楚了,要避免在系统设计中出现,一个类的继承层次超过3层,则需考虑重构代码,或者从新设计结构。固然最好的办法就是考虑使用合成/聚合原则。

5.3 经过合成/聚合来进行复用的优缺点

优势:

1) 新对象存取成分对象的惟一方法是经过成分对象的接口。 
2) 这种复用是黑箱复用,由于成分对象的内部细节是新对象所看不见的。 
3) 这种复用支持包装。 
4) 这种复用所需的依赖较少。 
5) 每个新的类能够将焦点集中在一个任务上。 
6) 这种复用能够在运行时间内动态进行,新对象能够动态的引用与成分对象类型相同的对象。 
7) 做为复用手段能够应用到几乎任何环境中去。 
缺点:就是系统中会有较多的对象须要管理。

5.4 经过继承来进行复用的优缺点

优势: 
1)新的实现较为容易,由于超类的大部分功能能够经过继承的关系自动进入子类。

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

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

2) 若是超类发生改变,那么子类的实现也不得不发生改变。

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

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

此部分引用自:http://www.cnblogs.com/temptation/archive/2008/03/10/1098351.html

六.迪米特法则(Law of Demeter LoD)

5.1概述 
定义:一个软件实体应当尽量少的与其余实体发生相互做用。 
这样,当一个模块修改时,就会尽可能少的影响其余的模块。扩展会相对容易。 
这是对软件实体之间通讯的限制。它要求限制软件实体之间通讯的宽度和深度。 
5.2迪米特法则的其余表述: 
1)只与你直接的朋友们通讯。 
2)不要跟“陌生人”说话。 
3)每个软件单位对其余的单位都只有最少的知识,并且局限于那些与本单位密切相关的软件单位。 
5.3狭义的迪米特法则 
若是两个类没必要彼此直接通讯,那么这两个类就不该当发生直接的相互做用。若是其中的一个类须要调用另外一个类的某一个方法的话,能够经过第三者转发这个调用。 
朋友圈的肯定 
“朋友”条件: 
1)当前对象自己(this) 
2)以参量形式传入到当前对象方法中的对象 
3)当前对象的实例变量直接引用的对象 
4)当前对象的实例变量若是是一个汇集,那么汇集中的元素也都是朋友 
5)当前对象所建立的对象 
任何一个对象,若是知足上面的条件之一,就是当前对象的“朋友”;不然就是“陌生人”。 
缺点:会在系统里造出大量的小方法,散落在系统的各个角落。 
与依赖倒转原则互补使用 
5.4狭义的迪米特法则的缺点: 
在系统里造出大量的小方法,这些方法仅仅是传递间接的调用,与系统的商务逻辑无关。 
遵循类之间的迪米特法则会是一个系统的局部设计简化,由于每个局部都不会和远距离的对象有直接的关联。可是,这也会形成系统的不一样模块之间的通讯效率下降,也会使系统的不一样模块之间不容易协调。 
5.5迪米特法则与设计模式 
门面(外观)模式和调停者(中介者)模式实际上就是迪米特法则的具体应用。 
5.6广义的迪米特法则 
迪米特法则的主要用意是控制信息的过载。在将迪米特法则运用到系统设计中时,要注意下面的几点: 
1)在类的划分上,应当建立有弱耦合的类。 
2)在类的结构设计上,每个类都应当尽可能下降成员的访问权限。 
3)在类的设计上,只要有可能,一个类应当设计成不变类。 
4)在对其余类的引用上,一个对象对其对象的引用应当降到最低。 
5.7广义迪米特法则在类的设计上的体现 
1)优先考虑将一个类设置成不变类 
2)尽可能下降一个类的访问权限 
3)谨慎使用Serializable 
4)尽可能下降成员的访问权限 
5)取代C Struct 
迪米特法则又叫做最少知识原则(Least Knowledge Principle或简写为LKP),就是说一个对象应当对其余对象有尽量少的了解。 
5.8如何实现迪米特法则 
迪米特法则的主要用意是控制信息的过载,在将其运用到系统设计中应注意如下几点: 
1) 在类的划分上,应当建立有弱耦合的类。类之间的耦合越弱,就越有利于复用。 
2) 在类的结构设计上,每个类都应当尽可能下降成员的访问权限。一个类不该当public本身的属性,而应当提供取值和赋值的方法让外界间接访问本身的属性。 
3) 在类的设计上,只要有可能,一个类应当设计成不变类。 
4) 在对其它对象的引用上,一个类对其它对象的引用应该降到最低。

七.单一职责原则(Simple responsibility pinciple SRP)

一个类,应该只有一个职责。每个职责都是变化的一个轴线,若是一个类有一个以上的职责,这些职责就耦合在了一块儿。这会致使脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一块儿,会影响复用性。咱们可能只须要复用该类的某一个职责,但这个职责跟其它职责耦合在了一块儿,很难分离出来,即第7章提到的牢固性。

SRP中,把职责定义为“变化的缘由”。若是你能想到N个动机去改变一个类,那么这个类就具备多于一个的职责。这里说的“变化的缘由”,只有实际发生时才有意义。可能预测到会有多个缘由引发这个类的变化,但这仅仅是预测,并无真的发生,这个类仍可看作具备单一职责,不须要分离职责。若是分离,会带来没必要要的复杂性。

若是发现一个类有多于一个的职责,应该尽可能解耦。若是很难解耦,也要分离接口,在概念上解耦。

众所周知,OOPL能够提升程序的封装性、复用性、可维护性。但仅仅是“能够”。能不能实现OOPL的这些优势,要看具体怎么作。若是一个类的代码很是混乱,各类功能的代码都混在一块儿,封装性、复用性、可维护性无从谈起。

SRP是全部原则中最简单的,也是最基本的一个。运用这个原则,能够提升类的内聚性,有助于充分发挥OOPL的优点。

相关文章
相关标签/搜索