文档视界 最新最全的文档下载
当前位置:文档视界 › Java面向对象16种设计原则

Java面向对象16种设计原则

Java面向对象16种设计原则
Java面向对象16种设计原则

一类的设计原则

1依赖倒置原则-Dependency Inversion Principle (DIP)

2里氏替换原则-Liskov Substitution Principle (LSP)

3接口分隔原则-Interface Segregation Principle (ISP)

4单一职责原则-Single Responsibility Principle (SRP)

5开闭原则-The Open-Closed Principle (OCP)

二包的设计原则

6重用发布等价原则-Release ReuseEquivalency Principle (REP)

7无环依赖原则-The AcyclicDependencies Principle (ADP)

8稳定依赖原则-The StableDependencies Principle (SDP)

9稳定抽象等价原则-The StableAbstractions Principle (SAP)

10共同封闭原则-The CommonClosure Principle (CCP)

11全部重用原则-The Common Reuse Principle (CRP)

三扩展原则

12 迪米特法则-Least Knowledge Principle (LKP)

13 黑盒原则-BBP(Black Box Principle)

14 缺省抽象原则-DAP(Default Abstraction Principle)

15 接口设计原则-IDP(Interface Design Principle)

16 不要构造具体的超类原则-DCSP(Don't Concrete SupperclassPrinciple)

1. Dependency Inversion Principle (DIP) - 依赖倒置原则

依赖:在程序设计中,如果一个模块a使用或调用了另一个模块b,我们称模块a依赖模块b。高层模块与低层模块:往往在一个应用程序中,我们有一些低层次的类,这些类实现了一些基本的或初级的操作,我们称之为低层模块;另外有一些高层次的类,这些类封装了某些复杂的逻辑,并且依赖于低层次的类,这些类我们称之为高层模块。

依赖倒置原则的2个重要方针:

A. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象

B. 抽象不应该依赖于细节,细节应该依赖于抽象

为什么叫做依赖倒置(Dependency Inversion)呢?

面向对象程序设计相对于面向过程(结构化)程序设计而言,依赖关系被倒置了。因为传统的结构化程序设计中,高层模块总是依赖于低层模块。

问题的提出:

Robert C. Martin在原文中给出了“Bad Design”的定义:

1. 系统很难改变,因为每个改变都会影响其他很多部分。

2. 当你对某地方做一修改,系统的看似无关的其他部分都不工作了。

3. 系统很难被另外一个应用重用,因为你很难将要重用的部分从系统中分离开来。

导致“Bad Design”的很大原因是“高层模块”过分依赖“低层模块”。一个良好的设计应该是系统的每一部分都是可替换的。如果“高层模块”过分依赖“低层模块”,一方面一旦“低层模块”需要替换或者修改,“高层模块”将受到影响;另一方面,高层模块很难可以重用。

比如,一个Copy模块,需要把来自Keyboard的输入复制到Print,即使对Keyboard和Print 的封装已经做得非常好,但如果Copy模块里直接使用Keyboard与Print,Copy任很难被其他应用环境(比如需要输出到磁盘时)重用。

问题的解决:

为了解决上述问题,Robert C. Martin提出了OO设计的Dependency Inversion Principle (DIP) 原则。

DIP给出了一个解决方案:在高层模块与低层模块之间,引入一个抽象接口层。

High Level Classes(高层模块)--> Abstraction Layer(抽象接口层)--> Low Level Classes (低层模块)

抽象接口是对低层模块的抽象,低层模块继承或实现该抽象接口。

这样,高层模块不直接依赖低层模块,高层模块与低层模块都依赖抽象接口层。

当然,抽象也不依赖低层模块的实现细节,低层模块依赖(继承或实现)抽象定义。

Robert C. Martin给出的DIP方案的类的结构图:

PolicyLayer-->MechanismInterface(abstract)--MechanismLayer-->UtilityInterface(abstract)--Utilit yLayer

类与类之间都通过Abstract Layer来组合关系。

2. Liskov Substitution Principle (LSP) - 里氏替换原则

所有引用基类的地方必须能透明地使用其子类的对象。也就是说,只有满足以下2个条件的OO设计才可被认为是满足了LSP原则:

A 不应该在代码中出现if/else之类对子类类型进行判断的条件。以下代码就违反LSP定义。if (obj typeof Class1) {

do something

} else if (obj typeof Class2) {

do something else

}

B 子类应当可以替换父类并出现在父类能够出现的任何地方,或者说如果我们把代码中使

用基类的地方用它的子类所代替,代码还能正常工作。

里氏替换原则LSP是使代码符合开闭原则的一个重要保证。同时LSP体现了:

1)类的继承原则:如果一个继承类的对象可能会在基类出现地方出现运行错误,则该子类不应该从该基类继承,或者说,应该重新设计它们之间的关系。

2)动作正确性保证:从另一个侧面上保证了符合LSP设计原则的类的扩展不会给已有的系统引入新的错误。

类的继承原则:

Robert C. Martin举了Rectangle和Square的例子。这里沿用这个例子,但用Java语言对其加以重写,并忽略了某些细节只列出下面的精要部分来说明里氏替换原则对类的继承上的约束。

1class Rectangle {

2double width;

3double height;

4

5public double getHeight() {

6return height;

7}

8public void setHeight(double height) {

9this.height = height;

10}

11public double getWidth() {

12return width;

13}

14public void setWidth(double width) {

15this.width = width;

16}

17}

18

19class Square extends Rectangle {

20public void setHeight(double height) {

21super.setHeight(height);

22super.setWidth(height);

23}

24

25public void setWidth(double width) {

26super.setHeight(width);

27super.setWidth(width);

28}

29}

class Rectangle {

double width;

double height;

public double getHeight() {

return height;

}

public void setHeight(double height) {

this.height = height;

}

public double getWidth() {

return width;

}

public void setWidth(double width) {

this.width = width;

}

}

class Square extends Rectangle {

public void setHeight(double height) {

super.setHeight(height);

super.setWidth(height);

}

public void setWidth(double width) {

super.setHeight(width);

super.setWidth(width);

}

}

这里Rectangle是基类,Square从Rectangle继承。这种继承关系有什么问题吗?

假如已有的系统中存在以下既有的业务逻辑代码:

void g(Rectangle r) {

r.setWidth(5);

r.setHeight(4);

if (r.getWidth() * r.getHeight() != 20) {

throw new RuntimeException();

}

}

则对应于扩展类Square,在调用既有业务逻辑时:

Rectangle square = new Square();

g(square);

时会抛出一个RuntimeException异常。这显然违反了LSP原则。

动作正确性保证:

因为LSP对子类的约束,所以为已存在的类做扩展构造一个新的子类时,根据LSP的定义,不会给已有的系统引入新的错误。

Design by Contract

根据Bertrand Meyer提出的Design by Contract(DBC:基于合同的设计)概念的描述,对于类的一个方法,都有一个前提条件以及一个后续条件,前提条件说明方法接受什么样的参数数据等,只有前提条件得到满足时,这个方法才能被调用;同时后续条件用来说明这个方法完成时的状态,如果一个方法的执行会导致这个方法的后续条件不成立,那么此方法也不应该正常返回。

现在把前提条件以及后续条件应用到继承子类中,子类方法应该满足:

1)前提条件不强于基类.

2)后续条件不弱于基类.

换句话说,通过基类的接口调用一个对象时,用户只知道基类前提条件以及后续条件。因此继承类不得要求用户提供比基类方法要求的更强的前提条件,亦即,继承类方法必须接受任何基类方法能接受的任何条件(参数)。同样,继承类必须顺从基类的所有后续条件,亦即,继承类方法的行为和输出不得违反由基类建立起来的任何约束,不能让用户对继承类方法的输出感到困惑。这样,我们就有了基于合同的LSP,基于合同的LSP是LSP的一种强化。

在很多情况下,在设计初期我们类之间的关系不是很明确,LSP则给了我们一个判断和设计类之间关系的基准:需不需要继承,以及怎样设计继承关系。

3. Interface Segregation Principle (ISP) - 接口分隔原则

不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。它包含了2层意思:

1)接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法塞进同一个接口里。

如果一个接口的方法没有被使用到,则说明该接口过胖,应该将其分割成几个功能专一的接口。

2)接口的依赖(继承)原则:如果一个接口a依赖(继承)另一个接口b,则接口a相当于继承了接口b的方法,那么继承了接口b后的接口a也应该遵循上述原则:不应该包含用户不使用的方法。反之,则说明接口a被b给污染了,应该重新设计它们的关系。

如果用户被迫依赖他们不使用的接口,当接口发生改变时,他们也不得不跟着改变。换而言之,一个用户依赖了未使用但被其他用户使用的接口,当其他用户修改该接口时,依赖该接口的所有用户都将受到影响。这显然违反了开闭原则,也不是我们所期望的。

下面我们举例说明怎么设计接口或类之间的关系,使其不违反ISP原则。

假如有一个Door,有lock,unlock功能,另外,可以在Door上安装一个Alarm而使其具有报警功能。用户可以选择一般的Door,也可以选择具有报警功能的Door。

有以下几种设计方法:

ISP原则的违反例:

方法一:

在Door接口里定义所有的方法。图:

但这样一来,依赖Door接口的CommonDoor却不得不实现未使用的alarm()方法。违反了ISP 原则。

方法二:

在Alarm接口定义alarm方法,在Door接口定义lock,unlock方法,Door接口继承Alarm 接口。

跟方法一一样,依赖Door接口的CommonDoor却不得不实现未使用的alarm()方法。违反了ISP原则。

遵循ISP原则的例:

方法三:通过多重继承实现

Adapter设计模式的实现。

第2)种方案更具有实用性。

这种设计遵循了ISP设计原则。

方法四:通过委托实现

在Alarm接口定义alarm方法,在Door接口定义lock,unlock方法。接口之间无继承关系。CommonDoor实现Door接口,

AlarmDoor有2种实现方案:

1)同时实现Door和Alarm接口。

2)继承CommonDoor,并实现Alarm接口。该方案是继承方式的

小结

Interface Segregation Principle (ISP)从对接口的使用上为我们对接口抽象的颗粒度建立了判断基准:在为系统设计接口的时候,使用多个专门的接口代替单一的胖接口。

4. Single Responsibility Principle (SRP) - 单一职责原则

永远不要让一个类存在多个改变的理由。换句话说,如果一个类需要改变,改变它的理由永远只有一个。如果存在多个改变它的理由,就需要重新设计该类。

SRP(Single Responsibility Principle)原则的核心含意是:只能让一个类有且仅有一个职责。这也是单一职责原则的命名含义。

为什么一个类不能有多于一个以上的职责呢?

如果一个类具有一个以上的职责,那么就会有多个不同的原因引起该类变化,而这种变化将影响到该类不同职责的使用者(不同用户):

1,一方面,如果一个职责使用了外部类库,则使用另外一个职责的用户却也不得不包含这个未被使用的外部类库。

2,另一方面,某个用户由于某原因需要修改其中一个职责,另外一个职责的用户也将受到影响,他将不得不重新编译和配置。这违反了设计的开闭原则,也不是我们所期望的。

职责的划分

既然一个类不能有多个职责,那么怎么划分职责呢?

Robert.C Martin给出了一个著名的定义:所谓一个类的一个职责是指引起该类变化的一个原因。如果你能想到一个类存在多个使其改变的原因,那么这个类就存在多个职责。

Single Responsibility Principle (SRP)的原文里举了一个Modem的例子来说明怎么样进行职责的划分,这里我们也沿用这个例子来说明一下:

SRP违反例:

Modem.java

interface Modem {

public void dial(String pno); //拨号

public void hangup(); //挂断

public void send(char c); //发送数据

public char recv(); //接收数据

}

咋一看,这是一个没有任何问题的接口设计。但事实上,这个接口包含了2个职责:第一个是连接管理(dial, hangup);另一个是数据通信(send, recv)。很多情况下,这2个职责没有任何共通的部分,它们因为不同的理由而改变,被不同部分的程序调用。

所以它违反了SRP原则。

下面的类图将它的2个不同职责分成2个不同的接口,这样至少可以让客户端应用程序使用具有单一职责的接口:

让ModemImplementation实现这两个接口。我们注意到,ModemImplementation又组合了2个职责,这不是我们希望的,但有时这又是必须的。通常由于某些原因,迫使我们不得不绑定多个职责到一个类中,但我们至少可以通过接口的分割来分离应用程序关心的概念。

事实上,这个例子一个更好的设计应该是这样的,如图:

小结

Single Responsibility Principle (SRP)从职责(改变理由)的侧面上为我们对类(接口)的抽象的颗粒度建立了判断基准:在为系统设计类(接口)的时候应该保证它们的单一职责性。

5. The Open-Closed Principle (OCP) - 开闭原则

开闭原则(OCP:Open-Closed Principle)是指在进行面向对象设计(OOD:Object Oriented Design)中,设计类或其他程序单位时,应该遵循:

- 对扩展开放(open)

- 对修改关闭(closed)

开闭原则是判断面向对象设计是否正确的最基本的原理之一。根据开闭原则,在设计一个软

件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)的基础上,能扩展其功能(扩展开放)。

A 扩展开放:某模块的功能是可扩展的,则该模块是扩展开放的。软件系统的功能上的可扩展性要求模块是扩展开放的。

B 修改关闭:某模块被其他模块调用,如果该模块的源代码不允许修改,则该模块修改关闭的。软件系统的功能上的稳定性,持续性要求是修改关闭的。

这也是系统设计需要遵循开闭原则的原因:

1)稳定性。开闭原则要求扩展功能不修改原来的代码,这可以让软件系统在变化中保持稳定。2)扩展性。开闭原则要求对扩展开放,通过扩展提供新的或改变原有的功能,让软件系统具有灵活的可扩展性。

遵循开闭原则的系统设计,可以让软件系统可复用,并且易于维护。

开闭原则的实现方法

为了满足开闭原则的对修改关闭(closed for modification)原则以及扩展开放(open for extension)原则,应该对软件系统中的不变的部分加以抽象,在面向对象的设计中,

A 可以把这些不变的部分加以抽象成不变的接口,这些不变的接口可以应对未来的扩展;

B 接口的最小功能设计原则。根据这个原则,原有的接口要么可以应对未来的扩展;不足的部分可以通过定义新的接口来实现;

C 模块之间的调用通过抽象接口进行,这样即使实现层发生变化,也无需修改调用方的代码。

接口可以被复用,但接口的实现却不一定能被复用。接口是稳定的,关闭的,但接口的实现是可变的,开放的。可以通过对接口的不同实现以及类的继承行为等为系统增加新的或改变系统原来的功能,实现软件系统的柔软扩展。

简单地说,软件系统是否有良好的接口(抽象)设计是判断软件系统是否满足开闭原则的一种重要的判断基准。现在多把开闭原则等同于面向接口的软件设计。

开闭原则的相对性

软件系统的构建是一个需要不断重构的过程,在这个过程中,模块的功能抽象,模块与模块间的关系,都不会从一开始就非常清晰明了,所以构建100%满足开闭原则的软件系统是相当困难的,这就是开闭原则的相对性。但在设计过程中,通过对模块功能的抽象(接口定义),模块之间的关系的抽象(通过接口调用),抽象与实现的分离(面向接口的程序设计)等,可以尽量接近满足开闭原则。

6. Release Reuse Equivalency Principle (REP) - 重用发布等价原则

包的内部关系方面(聚合性)的原则,重用粒度等价于发布粒度。重用主要是从用户的观点来看的。对用户来说,使用某个发布单位(组件,类,类群等),如果作者因为某种原因对其作了修改而发布了一个新的版本,用户会期望在升级为新版本之后,不会影响到原系统的正常运作。

也就是说,对于一个可重用(能供其它用户或系统使用)的元素(组件,类,类群等),作者应该承诺新版本能够兼容旧版本。否则,用户将拒绝使用该元素。

Robert C. Martin给出的对重用的定义:

代码可以看作为可重用的代码,当且仅当:

- 它的使用者(下称用户)无需看它的源代码

- 用户只需联结静态库或包含动态库

- 当库发生改变(错误纠正,功能增强)时,用户只需要得到一个新的版本便能集成到原有的系统

怎么做到重用呢?

一个组件要做到能够重用,它必须有一个得到良好设计的结构,它所包含所有元素必须也是可以重用的。

因为如果一个为重用而设计的发布单位里,包含了不可重用的元素,当不可重用的元素发生改变时,用户也不得不改变原有系统以适应新的版本。这显然违反了重用的定义规则。

也就是说,一个为重用目的而设计的发布单位里,不能包含不可重用的元素;如果包含了不可重用的元素,它将变得不可重用。

发布单位

当用户使用的重用组件被作者修改后,用户希望得到通知,然后决定是否升级或升级的时机。为了能使升级后的系统也能正常运作,用户也希望作者有一个规范的发布,包括版本号,类库的说明等等。

一旦用户决定升级新版本,不管这些修改是否影响到用户,用户也不得不包含新版本所包含的所有类库。

REP规定重用粒度不能小于发布粒度,所有重用元素也必须被一起发布。

发布粒度可以为包(组件)或类等实体,但一个应用往往包含了很多类,所以,具有更大的尺度的包(组件)更加适合作为发布粒度。

重用发布等价原则为我们指明了包的设计方针:一个包中的元素(类)要么都可重用,要么都不可重用。

小结

重用发布等价原则(REP)从用户观点的角度上为我们规范了包设计的原则:在设计包时,包中应该包含的元素要么都可以重用,要么都不可以重用。

7. The Acyclic Dependencies Principle (ADP) - 无环依赖原则

包之间的依赖结构必须是一个直接的无环图形(DAG)。也就是说,在依赖结构中不允许出现环(循环依赖)。换成另一个说法是:包间依赖不能是一个环状形式。包间关系方面(耦合性)的原则

包的依赖

如果一个包A 中的类引用了包B中的类,我们称包A依赖包B。

“依赖”在具体的程序语言中表现为,如果A依赖B,C/C++语言则在A包的文件/类中通过#include语句包含B包中的文件/类;Java语言则A包的类中通过import语句引入B包中的类。

图1(包A依赖包B)

虚线表示一种依赖关系,箭头表示依赖的方向,箭头所在的一侧就是被依赖的包。

包的循环依赖

我们上面讨论了并用图形表示了包之间的依赖关系。如果存在2个或2个以上的包,它们之间的依赖关系图出现了环状,我们就称包之间存在循环依赖关系。

也就是说它们的依赖结构图根据箭头的方向形成了一个环状的闭合图形。如图:

图2:包的循环依赖

如图:A依赖B,B依赖C,C依赖A,形成了一个环状依赖。

包的非循环依赖原则

包是一个比较合适的发布粒度,当修改了包中的代码(类,模块等)并发布新的版本时,我们需要把该包以及它所依赖的其它包一起发布。发布之后,还需要验证系统是否能在新发布的版本下正常运作。

如果多个包之间形成了循环依赖,比如如图2,A依赖B,B依赖C,C依赖A,我们修改了B并需要发布B的一个新的版本,因为B依赖C,所以发布时应该包含C,但C同时又依赖A,所以又应该把A也包含进发布版本里。也就是说,依赖结构中,出现在环内的所有包都不得不一起发布。它们形成了一个高耦合体,当项目的规模大到一定程度,包的数目变多时,包与包之间的关系便变得错综复杂,各种测试也将变得非常困难,常常会因为某个不相关的包中的错误而使得测试无法继续。而发布也变得复杂,需要把所有的包一起发布,无疑增加了发布后的验证难度。

循环依赖的打破方法

如果包的依赖形成了环状结构,怎么样打破这种循环依赖呢?

有2种方法可以打破这种循环依赖关系:第一种方法是创建新的包,第二种方法是使用DIP(依赖倒置原则)和ISP(接口分隔原则)设计原则。

方法一:创建新的包

比如对于图2这种依赖结构:

图2:包的循环依赖

包C要依赖包A,必定A中包含有A,C共通使用的类,把这些共同类抽出来放在一个新的包D里。这样就把C依赖A变成了C依赖D以及A依赖D,从而打破了循环依赖关系。如图:

这样,包的依赖关系就从A->B->C->A变成了:

A->B->C->D

A->D

方法二:DIP与ISP设计原则

ISP(接口分隔原则)可以剔除美用到的接口。DIP(依赖倒置原则)在类的调用之间引入抽象层。

如图,,包A依赖包B(因为包A中的类U使用了包B中的类X);反过来,包B又依赖包A (因为包B中的类Y使用了包A中的类V)

包A,包B之间就形成了一种循环依赖。

我们使用DIP设计原则为V抽象一个接口IVforY,并把该接口放在B包中。

这样就把Y对V的调用转化为:

V继承IVforY

Y调用IVforY

如图:

这样一来,包B中的类就不依赖任何包A中的类了。

小结

无环依赖原则(ADP)为我们解决包之间的关系耦合问题。在设计包结构时,不能有循环依赖。

8. The Stable Dependencies Principle (SDP) - 稳定依赖原则

一个设计中的包之间的依赖应该朝着稳定的方向进行。一个包只应该依赖那些比自己更稳定的包。换成另一个说法是:朝着稳定的方向进行依赖。包之间的关系方面(耦合性)的原则。

包的依赖

如果一个包A 中的类引用了包B中的类,我们称包A依赖包B。

“依赖”在具体的程序语言中表现为,如果A依赖B,C/C++语言则在A包的文件/类中通过#include语句包含B包中的文件/类;Java语言则A包的类中通过import语句引入B包中的类。

图1(包A依赖包B)

虚线表示一种依赖关系,箭头表示依赖的方向,箭头所在的一侧就是被依赖的包。

包的稳定依赖原则

包应该依赖比自己更稳定的包。因为如果依赖一个不稳定的包,那么当这个不稳定的包发生变化时,本身稳定的包也不得不发生变化,变得不稳定了。

所谓稳定,在现实生活中是指一个物体具有稳固不变的属性使它很难发生变化。应用到软件概念上,我们认为一个软件是稳定的,是因为这个软件很难发生改变,或更确切地说,是不需要发生改变。一个设计良好,能应对各种变化不需要修改的软件当然是稳定的了,但事实

上,往往一个软件常常需要对应某个事先没有预测到的用户需求而不得不发生改变,当这种改变发生时,能把修改控制在最小的范围之内,并能稳定的工作(包括软件本身以及依赖它的其它软件实体等),我们也会认为该软件是相对稳定的。

怎么样让一个软件足够稳定呢?一个确切的方法是,让大量其它软件的包依赖它。一个包被很多其他包依赖是非常稳定的,这是因为被依赖的包为了协调其他包必须做很多的工作来对应各种变化(责任的负担者)。

图1:稳定的包X

我们认为X是稳定的,因为:

- X被很多其他包依赖。相当于责任担当着。

- X没有依赖别的包,它是独立的。

相反,下面列出了一个非常不稳定的包Y,如图:

图2:不稳定的包Y

我们认为Y是不稳定的,因为:

- Y没有被其他的包所依赖。不是责任的担当着。

- Y依赖很多别的包。

包的稳定性的判断原则

可以通过下面的方法来判断一个包的稳定系数:

Ca:Afferent Coupling。向心耦合。依赖该包(包含的类)的外部包(类)的数目(i.e. incoming dependencies)。

Ce:Efferent Coupling。离心耦合。被该包依赖的外部包的数目(i.e. outgoing dependencies)。I:Instability。不稳定性。I=Ce/(Ce+Ca)。它的值处于[0,1]之间。

如图1,X的Ce=0,所以不稳定性I=0,它是稳定的。相反,如图2,Y的Ce=3,Ca=0,所以它的不稳定性I=1,它是不稳定的。

SDP要求一个包的不稳定性I要大于它所依赖的包的不稳定性。换句话说,沿着依赖的方向,包的不稳定性应该逐渐降低,稳定性应该逐渐升高。

稳定依赖原则(SDP)为我们解决包之间的关系耦合问题。在设计包结构时,包应该只依赖比自己更稳定的包。

9. The Stable AbstractionsPrinciple (SAP) - 稳定抽象等价原则

最稳定的包应该是最抽象的包。不稳定的包应该是具体的包。包的抽象程度跟它的稳定性成正比。稳定的包应该是抽象的包。

包的稳定抽象等价原则

我们在The Stable Dependencies Principle (SDP) - OO设计的稳定依赖原则一文中谈到了包的稳定性:不容易改变的包应该具有更好的稳定性。

一个包的抽象程度越高,它的稳定性就越高。反之,它的稳定性就越低。一个稳定的包必须是抽象的,反之,不稳定的包必须是具体的。

稳定的包的构成

抽象类或接口通过子类继承扩展行为,这表示抽象类或接口比它们的子类更具有稳定性。总之,为了构成稳定的包,应该提高包内的抽象类或接口的比率;它们的子类可以放在另一个不稳定的包内,该包依赖上述稳定的包,从而遵循了稳定依赖原则(SDP)。

理想的体系结构应该是:

不稳定的(容易改变的)包处于上层

- 它们是具体的包实现

稳定的(不容易改变的)包处于下层

- 不容易改变,但容易扩展

- 接口比实现(具体的运行代码)在内在特性上更具有稳定性

图1:遵循稳定依赖原则(SDP)的理想的体系结构

小结

稳定抽象等价原则(SAP)为我们解决包之间的关系耦合问题。在设计包结构时,稳定的包应该是抽象的(由抽象类或接口构成),不稳定的包应该是具体的(由具体的实现类构成)。

10. The Common ClosurePrinciple (CCP) - 共同封闭原则

一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同一个包里)。包的内部关系方面(聚合性)的原则

如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。

CCP原则就是把因为某个同样的原因而需要修改的所有类组合进一个包里。如果2个类从物理上或者从概念上联系得非常紧密,它们通常一起发生改变,那么它们应该属于同一个包。

CCP跟开闭原则(OCP: Open Closed Principle)有着很深的渊源关系,CCP的“关闭”(closure)就是OCP所提倡的:classes should be closed for modification but open for extension. 类应该对修改关闭,对扩展开放。但我们知道,100%的“关闭”是不现实的,我们在设计系统时,只能尽量地保持对大多数可预见的修改关闭。

CCP延伸了OCP的“关闭”概念,当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里。CCP原则帮助我们决定哪些类应该被放到同一个包里。

小结

共同封闭原则(CCP)从软件功能的角度上为我们规范了包设计的一个原则:在设计包时,相互之间紧密关联的类应该放在同一包里。

11. The Common Reuse Principle (CRP) - 全部重用原则

包的所有类被一起重用。如果你重用了其中的一个类,就重用全部。换成另一个比较浅显易懂的说法:没有被一起重用的类不应该被组合在一起。CRP原则帮助我们决定哪些类应该被放到同一个包里。包的内部关系方面(聚合性)的原则

依赖一个包就是依赖这个包所包含的一切。当一个包发生了改变,并发布新的版本,使用这个包的所有用户都必须在新的包环境下验证他们的工作,即使被他们使用的部分没有发生任何改变。

因为如果包中包含有未被使用的类,即使用户不关心该类是否改变,但用户还是不得不升级该包并对原来的功能加以重新测试。

“不能强迫用户去依赖那些他们不使用的接口”,把这个概念应用到更广范围的包上,就是CRP 的基本理念:不要把用户不使用的类一起组合进包里。

CRP与REP一样,都是从方便用户重用的角度去设计包,重用者是他们的受益者,CCP则让系统的维护者受益。CCP让包尽可能大(CCP原则加入功能相关的类),CRP则让包尽可能小(CRP原则剔除不使用的类)。它们的出发点不一样,但不相互冲突。CRP保证了包的内部具有很高的聚合性。

全部重用原则(CRP)从用户的角度上为我们规范了包设计的一个原则:在设计包时,相互之间没有紧密关联的类不应该放在同一包里。

12. Least Knowledge Principle (LKP) -迪米特法则

迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP)。一个对象应该对其他对象有最少的了解。通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的public方法,我就调用这么多,其他的一概不关心。

含义:

只和朋友交流

朋友类的定义是这样的:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。下面的代码在方法体内部依赖了其他类,这严重违反迪米特法则

01 public class Teacher {

02

03 public void commond(GroupLeader groupLeader) {

04 List listGirls = new ArrayList();

05

06 for (int i = 0; i < 20; i++) {

07 listGirls.add(new Girl());

08 }

09

10 groupLeader.countGirls(listGirls);

11 }

12

13 }

方法是类的一个行为,类竟然不知道自己的行为与其他类产生了依赖关系,这是不允许的。正确的做法是:

1 public class Teacher {

2

3 public void commond(GroupLeader groupLeader) {

4 groupLeader.countGirls();

5 }

6

7 }

01 public class GroupLeader {

02

03 private List listGirls;

04

05 public GroupLeader(List _listGirls) {

06 this.listGirls = _listGirls;

07 }

08

09 public void countGirls() {

10

System.out.println("女生数量是:" + listGirls.size());

11 }

12

13 }

注意:一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD()这种情况(在一种极端情况下允许出现这种访问,即每一个点号后面的返回类型都相同),类与类之间的关系是建立在类间的,而不是方法间,因此一个方法尽量不引入一个类中不存在的对象,当然,JDK API提供的类除外。

?朋友间也是有距离的

一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。因此,为了保持朋友类间的距离,在设计时需要反复衡量:是否还可以再减少public 方法和属性,是否可以修改为private、package-private(包类型,在类、方法、变量前不加访问权限,则默认为包类型)、protected等访问权限,是否可以加上final关键字等。

注意:迪米特法则要求类“羞涩”一点,尽量不要对外公布太多的public方法和非静态的public 变量,尽量内敛,多使用private、package-private、protected等访问权限。

?是自己的就是自己的

如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,就放置在本类中。

?谨慎使用Serializable

最后,迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。

Principle –纵览

----类原则----

1.单一职责原则-Single Responsibility Principle(SRP)

就一个类而言,应该仅有一个引起它变化的原因。

(职责即为“变化的原因”。)

2.开放-封闭原则- OpenClose Principle(OCP)

软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。

(对于扩展是开放的,对于更改是封闭的.

关键是抽象.将一个功能的通用部分和实现细节部分清晰的分离开来.

开发人员应该仅仅对程序中呈现出频繁变化的那些部分作出抽象.

拒绝不成熟的抽象和抽象本身一样重要. )

3.里氏替换原则-Liskov Substitution Principle(LSP)

子类型(subclass)必须能够替换掉它们的基类型(superclass)。

4.依赖倒置原则(IoCP) 或依赖注入原则-Dependence Inversion Principle(DIP)

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

(Hollywood原则: "Don't call us, we'll call you".

程序中所有的依赖关系都应该终止于抽象类和接口。

针对接口而非实现编程。

任何变量都不应该持有一个指向具体类的指针或引用。

任何类都不应该从具体类派生。

任何方法都不应该覆写他的任何基类中的已经实现了的方法。)

5.接口隔离原则(ISP)

不应该强迫客户依赖于它们不用的方法。

接口属于客户,不属于它所在的类层次结构。

(多个面向特定用户的接口胜于一个通用接口。)

----包内聚原则----

6.重用发布等价原则(REP)

重用的粒度就是发布的粒度。

7.共同封闭原则(CCP)

包中的所有类对于同一类性质的变化应该是共同封闭的。

一个变化若对一个包产生影响,

则将对该包中的所有类产生影响,

而对于其他的包不造成任何影响。

8.共同重用原则(CRP)

一个包中的所有类应该是共同重用的。

如果重用了包中的一个类,

那么就要重用包中的所有类。

(相互之间没有紧密联系的类不应该在同一个包中。)

----包耦合原则

9.无环依赖原则(ADP)

在包的依赖关系图中不允许存在环。

10.稳定依赖原则(SDP)

朝着稳定的方向进行依赖。

应该把封装系统高层设计的软件(比如抽象类)放进稳定的包中,

不稳定的包中应该只包含那些很可能会改变的软件(比如具体类)。

11.稳定抽象原则(SAP)

包的抽象程度应该和其稳定程度一致。

(一个稳定的包应该也是抽象的,一个不稳定的包应该是抽象的. )

----其它扩展原则----

12.BBP(Black Box Principle)黑盒原则

多用类的聚合,少用类的继承。

13.DAP(Default Abstraction Principle)缺省抽象原则

在接口和实现接口的类之间引入一个抽象类,这个类实现了接口的大部分操作.

14.IDP(Interface Design Principle)接口设计原则

规划一个接口而不是实现一个接口。

15.DCSP(Don't Concrete Supperclass Principle)不要构造具体的超类原则

避免维护具体的超类。

16.迪米特法则

一个类只依赖其触手可得的类。

结构化分析设计与面向对象分析设计比较研究

结构化分析设计与面向对象分析设计比较研究 重庆工商大学计算机科学与技术08软件龚霞 指导老师康世瀛 中文摘要:解析了结构化方法和面向对象方法这两种软件开发方法具有的分析设计过程,讨论了各自在不同软件开发中的应用及局限性,提出了在选用面向对象开发大型软件系统的同时可结合结构化方法。 关键词:软件开发;结构化方法;面向对象方法 Abstract:This paper anatomizes the analysis and design process of Structural method and objected-oriented method,discusses their applications and disadvantages and proposes that structural method can also be used while developing the large-scale software systems in selecting the objected-oriented method. Key words:software-development;objected-oriented method;structural method 一、引言 结构化方法由E.Yourdon和L.L.Constantine在1978年提出,结构化方法又可称为面向功能的软件开发方法或面向数据流的软件开发方法。结构化方法是建立在软件生存周期的模型基础上的一种软件开发方法,相对于早期的个体化开发方法无疑是前进了一大步。 由于传统的生命周期开发学存在下面的问题:生产率提高的幅度远不能满足需求,软件的重用度很低,软件难以维护,软件往往不能满足用户的需求。所以出现了面向对象软件开发方法。这是一种自底向上和自顶向下相结合的方法,而且它以对象建模为基础,从而不仅考虑了输入、输出数据结构,实际上也包含了所有对象的数据结构,所以面向对象的软件开发方法彻底实现了PAM没有完全实现的目标。不仅如此,面向对象技术在需求分析、可维护性和可靠性这三个软件开发的关键环节和质量指标上有了

面向对象设计原则

面向对象设计原则 ?OO原则: ◆封装变化之物 ◆针对接口编码,而不是对实现 ◆应用程序中的每一个类只有一个改变的理由 ◆类是关于行为与功能的 ?目的: 设计原则形成更可维护更具灵 ◆使用已被证实的OO设计原则形成更可维护、更具灵 活性以及更易扩展的软件 Design Principles ?OCP (The Open-Closed Principle) 开放-封闭原则 SRP(The Single Responsibility Principle)单职责原则?SRP (The Single-Responsibility Principle) 单一职责原则?LSP (The Liskov Substitution Principle) Liskov替换原则 ?DIP (The Dependency-Inversion Principle) 依赖倒置原则?ISP (The Interface-Segregation Principle) 接口隔离原则?CARP (Composition/Aggregation Principle ) 合成/聚合复用 原则 ?LoD(Law of Demeter) 迪米特法则

Open-Closed Principle ?开-闭原则(Open-Closed Principle) 对扩展开放对修改关闭 ◆对扩展开放,对修改关闭 ◆OCP允许改变,以不需要修改现有程序代码的方式 进行 SRP ?单一职责原则(SRP) 就一个类而言,应该仅有一个引起它变化的原因。 ◆就个类而言,应该仅有个引起它变化的原因。

Example: SRP violation interface Modem{ public void dial (String pno);ti public void dial (String pno);public void hangup();public void send (char c); public char recv();}connection management data communication Example Separated modem interface

问卷设计六大原则

问卷设计六大原则 问卷调查是目前调查业中所广泛采用的调查方式——即由调查机构根据调查目的设计各类调查问卷,然后采取抽样的方式(随机抽样或整群抽样)确定调查样本,通过调查员对样本的访问,完成事先设计的调查项目,最后,由统计分析得出调查结果的一种方式。它严格遵循的是概率与统计原理,因而,调查方式具有较强的科学性,同时也便于操作。这一方式对调查结果的影响,除了样本选择、调查员素质、统计手段等因素外,问卷设计水平是其中的一个前提性条件。而问卷设计的好坏很大程度上又与设计制度(原则)有关! 一、合理性。合理性指的是问卷必须紧密与调查主题相关。违背了这样一点,再漂亮或精美的问卷都是无益的。而所谓问卷体现调查主题其实质是在问卷设计之初要找出与“调查主题相关的要素”! 如:“调查某化妆品的用户消费感受”——这里并没有一个现成的选择要素的法则。但从问题出发,特别是结合一定的行业经验与商业知识,要素是能够被寻找出来的:一是使用者(可认定为购买者)。包括她(他)的基本情况(自然状况:如性别、年龄、皮肤性质等);使用化妆品的情况(是否使用过该化妆品、周期、使用化妆品的日常习惯等);二是购买力和购买欲。包括她(他)的社会状况收入水平、受教育程度、职业等);化妆品消费特点(品牌、包装、价位、产品外观等);使用该化妆品的效果(评价。问题应具有一定的多样性、但又限制在某个范围内,如Ⅰ.价格;Ⅱ.使用效果;Ⅲ.心理满足,等);三是产品本身。包括对包装与商标的评价、广告等促销手段的影响力、与市场上同类产品的横向比较、等……应该说,具有了这样几个要素对于调查主题的结果是有直接帮助的。被访问者也相对容易了解调查员的意图,从而予以配合。 二、一般性。即问题的设置是否具有普遍意义。 应该说,这是问卷设计的一个基本要求,但我们仍然能够在问卷中发现这类带有一定常识性的错误。这一错误不仅不利于调查成果的整理分析,而且会使调查委托方轻视调查者的水平。如搞一个“居民广告接受度”的调查: 问题:你通常选择哪一种广告媒体: 答案:a、报纸;b、电视;c、杂志;d、广播;e、其它 而如果答案是另一种形式: a、报纸; b、车票; c、电视; d、墙幕广告; e、汽球; f、大巴士; g、广告衫; h、…… 如果我们的统计指标没有那么细(或根本没必要),那我们就犯了一个“特殊性”的错误,从而导致某些问题的回答实际上是对调查无助的! 在一般性的问卷技巧中,需要注意的是:不能犯问题内容上的错误。如: 问题:你拥有哪一种信用卡? 答案:a、长城卡;b、牡丹卡;c、龙卡;d、维萨卡;e、金穗卡; ——其中“d”的设置是错误的,应该避免。 三、逻辑性。问卷的设计要有整体感,这种整体感即是问题与问题之间要具有逻辑性,独立的问题本身也不能出现逻辑上的谬误。从而使问卷成为一个相对完善的小系统。如: 问题: Ⅰ、你通常每日读几份报纸? a、不读报; b、1份; c、2份; d、3份以上; Ⅱ、你通常用多长时间读报? a、10分钟以内; b、半小时左右; c、1小时; d、1小时以上; Ⅲ、你经常读的是下面哪类(或几类)报纸? a、×市晚报; b、×省日报; c、人民日报; d、参考消息; e、中央广播电视报; f、足球…… 在以上的几个问题中,由于问题设置紧密相关,因而能够获得比较完整的信息。调查对象也会感到问题集中、提问有章法。相反,假如问题是发散的、带有意识流痕迹的,问卷就会给人以随意性而不是严谨性的感觉。那么,将市场调查作为经营决策的一个科学过程的企业就会对调查失去信心! 因此,逻辑性的要求即是与问卷的条理性、程序性分不开的。已经看到,在一个综合性的问卷中,调查者将差异较大的问卷分块设置,从而保证了每个“分块”的问题都密切相关。 四、明确性。所谓明确性,事实上是问题设置的规范性。这一原则具体是指:命题是否准确?提问是

UML面向对象分析与设计、建模与设计课后选择判断

第一章 1.选择题 (1)软件工程的概念是在()年被首次提出的。 A.1949 B.1968 C.1972 D.1989 (2)下列不属于软件工程的目标的一项是() A.提高软件产品的质量 B.提高软件产品的可靠性 C.减少软件产品的需求 D.控制软件开发成本 (3)软件危机产生的主要原因是() A.软件工具落后 B.软件生产能力不足 C.对软件认识不够 D.软件本身的特点及开发方法 (4)人们公认的第一门面向对象编程语言是()。 A. Simula B. Smalltalk C. C++ D. Java (5)下列编程语言中不支持面向对象的特性的是()。 A. C++ B. ANSI C C. Java D. Objetive c (6)下列选项中不是面向对象方法的相关原则的是()

A.封装 B.继承 C.多态 D.结构 (7)()是面向对象方法中用来描述”对客户隐藏对象的属性和实现细节”的概念。 A.封装 B.继承 C.多态 D.抽象 (8)下列选项中不属于面向对象方法的优势之-的是()。 A.复用性强 B.改善了软件结构 C.软件的执行效率更高 D.抽象更符合人类的思维习惯 2.判断题 (1)软件就是程序,编写软件就是编写程序。对错 (2)软件危机的主要表现是软件需求增加,软件价格上升。对错 (3) C语言对面向对象的发展起到了重要作用。对错 (4)面向对象方法中的对象是从客观世界中抽象出来的一个集合体。对错 (5)面向对象可以保证开发过程中的需求变化完全不会导致系统结构的变化。对错 (6)面向对象方法就是使用面向对象的程序设计语言进行编程。对错

(7)对象的自治性指的是对象是完全封闭的,不受任何外界影响。对错 (8)类是面向对象程序中的构造单位,也是面向对象程序设计语言的基本成分。对错 第二章 1.选择题 1.选择题 (1)下列关于模型的表述,不正确的项是()。 A.建模语言只能是图形表示的 B.模型所描绘的系统蓝團既可以包括详细的计划,也可以包括系统的总体计划 C.模型可以帮助开发组生成有用的工作产品 D.最好的模型总是与现实世界联系密切 (2) UML的全称是()。 A. Unify Modeling L.anguage B. Unified Modeling Language

六大设计原则

设计模式六大设计原则 单一职责原则(Single Responsibility Principle-SRP) 理解:对于一个类而言,应该仅有一个引起它变化的原因。说白了就是,不同的类具备不同的职责,各施其责。这就好比一个团队,大家分工协作,互不影响,各做各的事情。 应用:当我们做系统设计时,如果发现有一个类拥有了两种的职责,那就问自己一个问题:可以将这个类分成两个类吗?如果真的有必要,那就分吧。千万不要让一个类干的事情太多!开放封闭原则(open closed principle-OCP) 理解:简言之,对扩展开放,对修改封闭。换句话说,可以去扩展类,但不要去修改类。应用:当需求有改动,要修改代码了,此时您要做的是,尽量用继承或组合的方式来扩展类的功能,而不是直接修改类的代码。当然,如果能够确保对整体架构不会产生任何影响,那么也没必要搞得那么复杂了,直接改这个类吧。 里氏替换原则(liskov substitution principle -LSP) 理解:父类能够替换子类,但子类不一定能替换父类。也就是说,在代码中可以将父类全部替换为子类,程序不会报错,也不会在运行时出现任何异常,但反过来却不一定成立。 应用:在继承类时,务必重写(Override)父类中所有的方法,尤其需要注意父类的protected 方法(它们往往是让您重写的),子类尽量不要暴露自己的public 方法供外界调用。 最少知识原则(last knowledge principle-LKP) 理解:尽量减少对象之间的交互,从而减小类之间的耦合。简言之,一定要做到:低耦合,高内聚。 应用:在做系统设计时,不要让一个类依赖于太多的其他类,需尽量减小依赖关系,否则,您死都不知道自己怎么死的。 接口隔离原则(Interface Segregation Principle - ISP) 理解:不要对外暴露没有实际意义的接口。也就是说,接口是给别人调用的,那就不要去为难别人了,尽可能保证接口的实用性吧。她好,我也好。 应用:当需要对外暴露接口时,需要再三斟酌,如果真的没有必要对外提供的,就删了吧。一旦您提供了,就意味着,您将来要多做一件事情,何苦要给自己找事做呢。 依赖倒置原则(Dependence Inversion Principle – DIP) 理解:应该面向接口编程,不应该面向实现类编程。面向实现类编程,相当于就是论事,那是正向依赖(正常人思维);面向接口编程,相当于通过事物表象来看本质,那是反向依赖,即依赖倒置(程序员思维)。 应用:并不是说,所有的类都要有一个对应的接口,而是说,如果有接口,那就尽量使用接口来编程吧。

面向对象设计原则

面向对象设计原则

单一职责原则--SRP 一、SRP简介(SRP--Single-Responsibility Principle): 就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因。 所谓职责,我们可以理解他为功能,就是设计的这个类功能应该只有一个,而不是两个或更多。也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑撤分这个类了。因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化。“就像一个人身兼数职,而这些事情相互关联不大,,甚至有冲突,那他就无法很好的解决这些职责,应该分到不同的人身上去做才对。” 二、举例说明: 违反SRP原则代码: modem接口明显具有两个职责:连接管理和数据通讯; interface Modem { public void dial(string pno); public void hangup(); public void send(char c); public void recv(); } 如果应用程序变化影响连接函数,那么就需要重构: interface DataChannel { public void send(char c); public void recv(); } interface Connection {

public void dial(string pno); public void hangup(); } 三、SRP优点: 消除耦合,减小因需求变化引起代码僵化性臭味 四、使用SRP注意点: 1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责; 2、在没有变化征兆的情况下应用SRP或其他原则是不明智的; 3、在需求实际发生变化时就应该应用SRP等原则来重构代码; 4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码; 5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构;

六西格玛设计的8个基本原则

https://www.docsj.com/doc/737184862.html,/ 六西格玛设计的8个基本原则 简单地讲,六西格玛设计是为了满足顾客的要求和期望,并可为顾客带来价值和服务。六西格玛设计同传统设计一样,一些基本原则应该满足。否则,并非是一个成功的六西格玛设计项目。 1、性能指标适合要求的原则 每一种新产品或服务,性能指标必须达到顾客要求,这也是最低要求。新产品或服务的规格应该是清晰的,而且是可测量的。 2、实用性和舒适性的原则 每一种新产品或服务,要实用性和舒适性相结合,能使顾客满意,新产品设计要新颖,要符合美学原则。 3、创新性和超前性原则 每一种新的发明创造,能起到一种推动社会进步的作用。优秀的六西格玛设计师,是人类文明的开拓者。设计的项目具有创新精神和超前意识,为顾客带来新的愉悦,为社会创造价值,为人类作出贡献。 4、工艺性和可制造性原则 每一种新产品或服务设计出来,要能够形成商品,并快速投放市场,应该具有好的工艺性或可制造性。无论是加工或组装,工艺性能要满足制造要求,且夹具及辅料要最省,通用零部件要省,标准化程度要高。 5、可靠性原则 每一种新产品或服务设计出来,新产品要有一定的可靠度,满足顾客的预期使用寿命,为顾客真正带来价值。 6、可维修性原则 每一种新产品设计出来,在保障使用的前提下,可维修性也要提出来。尽量模块化、标准化、通用化,拆卸维修方便,提高产品的使用寿命,超越顾客的期望。 7、成本效益原则 每一种新产品的设计都要考虑成本与效益的问题,找到一个顾客与提供商的成本与效益的最佳平衡点。六西格玛设计师要系统考虑,全面统筹,给顾客带来价值的同时,要考虑给股东或社会带来价值。 8、安全性原则 每一种新产品或服务投放市场,应该是安全地满足顾客的要求和期望,六西格玛设计师要充分考虑设计的稳健性,提供必要的裕量。防止失效,防止给人类和社会造成灾难。这样的例子是不胜枚举的。往往是由于设计师的疏忽而酿成大祸。六西格玛设计师是人类灵魂的工程师,社会的进步,人类的发展,他们的作用是功不可没的。安全性要始终牢记于心,一种新产品或服务,要为社会带来福音。

面向对象分析与设计简答题

1、什么面向对象? 面向对象不仅是以些具体的软件开发技术与策略,而且以一套关于如何看待软件系统与现实世界的关系,以什么观点来研究问题并进行求解,以及如何进行系统构造的软件方法学。 2、软件开发方法学的基本方法有哪些? 1)软件工程和瀑布方法学2)新方法学:螺旋式、迭代式、递增式、合并式3)面向对象方法学:UML、RUP、XP 3、为什么需要OOA、OOD。 OOA就是运用面向对象的方法进行需求分析,OOA加强了对问题域和系统责任的理解,有利于人员之间的交流,对需求变化的适应性较强,很好的支持软件复用。 OOD就是运用面向对象的方法进行系统设计,OOD.符合人们习惯的思维方法,便于分解大型的复杂多变的问题;易于软件的维护和功能的增减;可重用性好;与可视化技术相结合,改善了工作界面。 4、从概念层次、规格层次、实现层次三个角度如何理解对象的概念? 从概念层次来看,一个对象就是一系列的责任; 从规格层次来看,一个对象是一系列可以被其他对象或该对象自己调用的方法;从实现层次来看,一个对象是一些代码和数据。 5、如何绘制类图和对象图?简述其步骤。 类图绘制:1发现类,找到备选类,确定候选类2关联分析,确定关联关系,多重性分析3职责分析4限定与修改,导航性分析,约束,限定符; 对象图绘制:1发现类和对象2对其细化,分析,确定关系。 6、简述重定义方法与重载的区别。 重定义:1参数列表必须完全与被重写的方法相同2返回类型必须一直域被重写的方法的类型相同3访问修饰符的限制一定要大于被重写方法的访问修饰符4重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查性异常:重载:1必须有不同参数列表2可以有不同的返回类型,只要参数列表不同即可3可有不同访问修饰符4可抛出不同的异常。 7.简述抽象方法与虚方法的联系与区别 虚方法有一个实现部分可以为子类实现有共同的方法,并为派生提供了覆盖该方法的选,抽象方法只是强制派生覆盖方法;抽象方法只能在抽象类中声明,而虚方法不是;抽象方法不能声明方法实体,虚方法可以;包含抽象方法的类不能实例化,但虚方法可以。 8、简述使用继承的规则。 1)、不要过度使用;2)、子类应是超类的一个类型;3)、子类应是超类的扩展; 4)、尽量少从具体类继承,最好继承接或抽象类。

面向对象分析设计原则

一、单一职责原则(SRP) 就一个类而言,应该仅有一个引起它变化的原因。软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。测试驱动的开发实践常常会在设计出现臭味之前就迫使我们分离职责。 二、开闭原则(OCP) 软件实体(类、模块、函数)应该是可扩展的,但是不可修改的。也就是说:对于扩展是开放的,对于更改是封闭的。怎样可能在不改动模块源代码的情况下去更改它的行为呢?怎样才能在无需对模块进行改动的情况下就改变它的功能呢?关键是抽象!因此在进行面向对象设计时要尽量考虑接口封装机制、抽象机制和多态技术。该原则同样适合于非面向对象设计的方法,是软件工程设计方法的重要原则之一。 三、替换原则(LSP) 子类应当可以替换父类并出现在父类能够出现的任何地方。这个原则是Liskov于1987年提出的设计原则。它同样可以从Bertrand Meyer 的DBC (Design by Contract〔基于契约设计〕) 的概念推出。 四、依赖倒置原则(DIP) 1、高层模块不应该依赖于低层模块。二者都应该依赖于抽象。2、抽象不应该依赖于细节。细节应该依赖于抽象。在进行业务设计时,与特定业务有关的依赖关系应该尽量依赖接口和抽象类,而不是依赖于具体类。具体类只负责相关业务的实现,修改具体类不影响与特定业务有关的依赖关系。在结构化设计中,我们可以看到底层的模块是对高层抽象模块的实现(高层抽象模块通过调用底层模块),这说明,抽象的模块要依赖具体实现相关的模块,底层模块的具体实现发生变动时将会严重影响高层抽象的模块,显然这是结构化方法的一个"硬伤"。面向对象方法的依赖关系刚好相反,具体实现类依赖于抽象类和接口。 五、接口分离原则(ISP) 采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。ISP原则是另外一个支持诸如COM等组件化的使能技术。缺少ISP,组件、类的可用性和移植性将大打折扣。这个原则的本质相当简单。如果你拥有一个针对多个客户的类,为每一个客户创建特定业务接口,然后使该客户类继承多个特定业务接口将比直接加载客户所需所有方法有效。 以上五个原则是面向对象中常常用到的原则。此外,除上述五原则外,还有一些常用的经验诸如类结构层次以三到四层为宜、类的职责明确化(一个类对应一个具体职责)等可供我们在进行面向对象设计参考。但就上面的几个原则看来,我们看到这些类在几何分布上呈现树型拓扑的关系,这是一种良好、开放式的线性关系、具有较低的设计复杂度。一般说来,在软件设计中我们应当尽量避免出现带有闭包、循环的设计关系,它们反映的是较大的耦合度和设计复杂化。 面向对象之代码复用规则 1、对接口编程 "对接口编程"是面向对象设计(OOD)的第一个基本原则。它的含义是:使用接口和同类型的组件通讯,即,对于所有完成相同功能的组件,应该抽象出一个接口,它们都实现该接口。具体到JAVA中,可以是接口,或者是抽象类,所有完成相同功能的组件都实现该接口,或者从该抽象类继承。尽量使用接口。接口只是对象打交道的入口,只有具有继承关系才使用抽象类。 2、优先使用对象组合,而不是类继承 "优先使用对象组合,而不是类继承"是面向对象设计的第二个原则。并不是说继承不重要,而是因为每个学习OOP的人都知道OO的基本特性之一就是继承,以至于继承已经被滥用了,而对象组合技术往往被忽视了。只有有现实生活中的父子关系才使用继承。 相关的设计模式有:Bridge、Composite、Decorator、Observer、Strategy等。 3、将可变的部分和不可变的部分分离 "将可变的部分和不可变的部分分离"是面向对象设计的第三个原则。如果使用继承的复用技术,我们

商业空间设计的6大原则

商业空间设计最终的目的有且只有一个 那就是让消费者迈入店铺门槛,并引导他们消费更多 这也是众多零售商想尽办法想要达到的目的 他们通过播放音乐或采用诱人的气味充满整个售卖场所等等的方式 去赢得顾客的关注与消费。 而对于商业空间设计公司来说 从最初的店面的规划,到实施,再到最后的交付 其设计的诀窍是了解消费者,设计出符合消费者喜好的室内环境 这才是商业空间设计真正的艺术所在。 下面的六种商业空间设计艺术将改变零售环境: 1.引人注目的视觉营销 商业空间设计中的橱窗所带来的视觉营销力是不容小觑的。引人注目的视觉营销可以吸引购物者的注意力,并鼓励他们走进商店消费。 橱窗是所有零售店的眼睛,透过这双眼睛,可以向顾客讲述商店的故事。这个故事的每一个细节,都有可能走进顾客的心里,牵动顾客将步代迈入商店内。通常来说,橱窗的展示核心在于店铺的核心商品。

2.减慢客户的购物过程 现代消费者非常忙碌,并且倾向于匆忙购物。商业空间设计的工作是减缓 这段购物过程并增加顾客在商店的停留时间。一种方法是在入口处放置一个醒 目的大型显示屏。 客户将很快知道他们是否喜欢他们所看到的内容,并将关键产品放在商店 前面可以帮助他们做出这个决定。通过一些动线的设计,零售商可以鼓励顾客 进一步进入商店的最深层。 3.动线引导顾客的购物路径 在进行商业空间设计时,零售商应该清楚的知道,他们规划的顾客动线, 应清楚地了解,哪些产品放在什么位置会有利于引导顾客走入商店的最深层, 接触更多深层的商,品,最终获得最多的消费。 一些零售商没有合理的动线设计,没有高效的将顾客带入他们想去的地方,只是单纯的引导顾客进入走道而没有考虑去设计出一条能增加停留时间、利于 销售的动线。 而商业空间设计中的动线设计原则,是设计出一条理想的客户购物路线. 4.引导顾客到商店右侧

第6章 面向对象设计原则

1 第06章面向对象的设计原则Object-Oriented Design Principles -1- 2 -2- 学习路线图 OO UML OOP DP … Case-Study … 学习路线图 : : …… …… …… (1) 2 34 5 6 7 8 9 10 3从问题开始! ?长方形与正方形 –假如我们有一个类:长方形(Rectangle) –我们需要一个新的类,正方形(Square) –问:可否直接继承长方形? 没问题,因为数学上正方形就是长方形的子类!height : int width : int getHeight() : int getWidth() : int setHeight(h : setWidth(w : int) setHeight(h : int) setWidth(w : int)

7-7--7-面向对象的设计原则 ?面向对象的设计原则 –是面向对象设计的基本指导思想–是评价面向对象设计的价值观体系–是设计模式的出发点和归宿 ?面向对象的设计原则是构造高质量软件的出发点 8 -8--8- 设计目标 ?构造出高质量软件,以保持系统稳定?设计目标 –可扩展性(Extensibility )–灵活性(Flexibility )–可插入性(Pluggability )– …… 9-9--9- 设计质量:培养灵敏的嗅觉 ?糟糕的设计总是散发出臭味,让人不悦 –判断一个设计的好坏,主观上能否让你的合作方感到心情愉悦,是最直观的标准 ?设计开发人员要培养嗅觉,当你看到UML 图或者代码,感到杂乱、繁琐、郁闷的时候,你可能正面对一个糟糕的设计 ?这种嗅觉是在实践开发中培养起来的,而面向对象设计原则对此加以归纳和总结 10 -10--10- 设计质量:坏的设计 ?什么是坏的设计? –僵硬性(Rigidity ):刚性,难以扩展–脆弱性(Fragility ):易碎,难以修改 –牢固性(Immobility ):无法分解成可移植的组件 –不必要的复杂性(Needless Repetition ):Ctrl C + Ctrl V –晦涩性(Opacity ):不透明,很难看清设计者的真实意图 11-11--11- 设计质量:好的设计 ?什么是好的设计? –容易理解 –容易修改和扩展–容易复用 –容易实现与应用 – 简单、紧凑、经济适用 ?让人工作起来心情愉快的设计 ?设计原则是提高设计质量的基本原则 12 -12--12- 面向对象的基本设计原则 ?LSP :Liskov 替换原则 –The Liskov Substitution Principle ?OCP :开放-封闭原则 –The Open-Close Principle ?SRP :单一职责原则 –The Single Responsibility Principle ?ISP :接口隔离原则 –The Interface Segregation Principle ?DIP :依赖倒置原则 –The Dependency Inversion Principle ?……

面向对象的设计原则之四大黄金法则

一些 面向对象的设计 法则 Bob T arr 著 outmyth 译

法则1:优先使用(对象)组合,而非(类)继承 [ Favor Composition Over Inheritance ] 组合 ?(对象)组合是一种通过创建一个组合了其它对象的对象,从而获得新功能的复用方法。 ?将功能委托给所组合的一个对象,从而获得新功能。 ?有些时候也称之为“聚合”(aggregation)或“包容”(containment),尽管有些作者对 这些术语赋予了专门的含义 ?例如: ?聚合:一个对象拥有另一个对象或对另一个对象负责(即一个对象包含另一个对象或是另一个对象的一部分),并且聚合对象和其所有者具有相同的生命周期。(译者 注:即所谓的“同生共死”关系,可参见GOF的Design Patterns: Elements of Reusable Object-Oriented Software的引言部分。) ?包容:一种特殊类型的组合,对于其它对象而言,容器中的被包含对象是不可见的,其它对象仅能通过容器对象来访问被包含对象。(Coad) ?包含可以通过以下两种方式实现: ?根据引用(By reference) ?根据值(By value) ?C++允许根据值或引用来实现包含。 ?但是在Java中,一切皆为对象的引用! 组合的优点和缺点 ?优点: ?容器类仅能通过被包含对象的接口来对其进行访问。 ?“黑盒”复用,因为被包含对象的内部细节对外是不可见。 ?对装性好。 ?实现上的相互依赖性比较小。(译者注:被包含对象与容器对象之间的依赖关系比较少) ?每一个类只专注于一项任务。 ?通过获取指向其它的具有相同类型的对象引用,可以在运行期间动态地定义(对象的)组合。

面向对象设计原则概述

面向对象设计原则概述 对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平。 面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一,在设计模式的学习中,大家经常会看到诸如“XXX模式符合XXX原则”、“XXX模式违反了XXX原则”这样的语句。 最常见的7种面向对象设计原则如下表所示: 表1 7种常用的面向对象设计原则

面向对象设计原则之单一职责原则 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。单一职责原则定义如下: 单一职责原则告诉我们:一个类不能太“累”!在软件系统中,一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小,而且一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。 单一职责原则是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。 下面通过一个简单实例来进一步分析单一职责原则: 在图1中,CustomerDataChart类承担了太多的职责,既包含与数据库相关的方法,又包含与图表生成和显示相关的方法。如果在其他类中也需要连接数据库或者使用findCustomers()方法查询客户信息,则难以实现代码的重用。无论是修改数据库连接方式还是修改图表显示方式都需要修改该类,它不止一个引起它变化的原因,违背了单一

面向对象分析与设计试题B卷

面向对象分析与设计试题B卷 一、单项选择题( 在每小题的四个备选答案中,选出一个正确答案,并将正确答案的序号填在题干的括号内。每小题2 分,共20 分) 1.到20世纪末,面向对象软件工程已经逐渐发展成熟,特别是( D )的 形成和广泛使用,采用面向对象分析与编程的软件开发方法已成为软件开发的主流方法。A. Simula67语言 B. Smalltalk语言 C. Java语言 D. 统一建模语言(UML)的标准 2. 面向对象的运动产生了多种面向对象的语言, 其中(C )是一种混合性面向对象语言, 既支持面向过程的程序设计方法,又支持面向对象的程序设计方法,有广泛应用的基础和丰富开发环境的支持,因而使面向对象的程序设计能得到很快普及。 A. Smalltalk B. Eiffel C. C++ D. Java 3.下列不属于面向对象技术的基本特征的是(B )。 A. 封装性 B. 模块性 C. 多态性 D. 继承性 4. 面向对象程序设计将描述事物的数据与(C ) 封装在一起,作为一个相互依存、不可分割的整体来处理。 A. 信息 B. 数据隐藏 C. 对数据的操作 D. 数据抽象 5. 关于面向对象方法的优点,下列不正确的叙述是(C )。 A. 与人类习惯的思维方法比较一致 B. 可重用性好 C. 以数据操作为中心 D.可维护性好 6. (D )是从用户使用系统的角度描述系统功能的图形表达方法。 A. 类图 B. 对象图 C. 序列图 D. 用例图 7. ( C ) 是表达系统类及其相互联系的图示,它是面向对象设计的核心,建立状态图、协作图 和其他图的基础。 A.对象图 B. 组件图 C. 类图 D. 配置图 8.(D )描述了一组交互对象间的动态协作关系,它表示完成某项行为的对象和这些对象 之间传递消息的时间顺序。 A.对象图 B. 协作图 C. 状态图 D. 序列图 9.(D )就是用于表示构成分布式系统的节点集和节点之间的联系的图示,它可以表示系 统中软件和硬件的物理架构。 A. 组件图 B. 协作图 C. 状态图 D. 配置图 10. 使用UML进行关系数据库的(B )时,需要设计出表达持久数据的实体类及其联系,并把它们映射成为关系数据库表(Table)、视图(View)等。 A. 业务Use Case模型设计 B. 逻辑数据模型设计 C. 物理数据模型设计 C. 物理实现设计 二、填空题( 每空1 分,共20 分) 1. 面向对象开发方法一改过去传统的以_____功能分析___为基础的_____面向对象_的结 构化分析与设计方法,它模拟人们理解和处理客观世界的方式来分析问题,把系统视为

广告海报设计的6大原则

广告海报设计的6大原则 导语:无规矩不成方圆,凡事都应该遵守原则,我们都知道广告对于我们很严重,广告海报设计的好可以为企业带来优良的效益,如今的社会是遵循优胜劣汰的生存法则,所以我们要增加自己的竞争力,更好的发展自己,因此宣传就很严重,然而广告海报设计在宣传上能起到很好的作用,下面就由为大家介绍一下广告海报设计的6大原则,希望对大家有所帮助! 一、冲击性原则。 在令人眼花缭乱的各种广告中,要想迅速吸引人们的视线,在广告公司创意海报就必须把提升视觉张力放在首位。 照片是广告中常用的视觉内容,将摄影艺术与电脑后期制作充分结合,拓展了广告公司创意海报的视野与表现手法,产生了剧烈的视觉冲击力,给观众留下了深刻的印象。 二、包蕴性原则。 吸引人们眼球的是形式,打动人心的是内容。独到醒目的形式必须蕴含耐人思索的深厚内容,才拥有吸引人一看再看的魅力。这就要求广告公司创意广告海报设计时不能停留在表层,而要使“本质”通过“表象”显现出来,这样才能有用地挖掘读者内心深处的渴望。 三、新奇性原则。新奇是广告作品引人注目的奥秘所在,也是一条不可忽视的广告创意规律。有了新奇,才能使广告公司创意海报波澜起伏,奇峰突起,引人入胜;有了新奇,才能使广告公司创意海报主题得到深化、升华。 四、应合理规划。 每一份广告海报设计的版面规划是否科学与规范也影响广告海报设计的广告效果的一个非常严重的条件。科学的对版面进行规划能够给大家造成一种比较好的视觉效果。 五、需构思要精巧。 产品的构思往往决定着一个产品能否得到大家的喜欢。 1/ 2

对于一份构思比较精巧的广告海报设计来说,无疑是会吸引大家关注的目光的,也是能够得到人们认可的一个非常严重的条件。 六、内容要全面充分。 因为广告海报设计最严重的一个要素就是广告宣传,所以,在设计广告海报设计的时候,应尽可能的把有关广告宣传的信息较好的融入到广告海报设计的中。 2/ 2

uml面向对象的分析与设计考题与答案

u m l面向对象的分析与设计考题与答案 集团文件版本号:(M928-T898-M248-WU2669-I2896-

《面向对象的分析与设计》练习题 一、选择题 1.UML 语言不支持的建模方式有(D )。 A. 静态建模 B.动态建模 C. 模块化建模 D. 功能建模 2.一个设计得好的OO系统具有( B )。 A. 低内聚、低耦合的特征 B.高内聚、低耦合的特征 C. 高内聚、高耦合的特征 D.低内聚、高耦合的特征 3.下列不属于面向对象技术的基本特征的是( B)。 A. 封装性 B. 模块性 C. 多态性 D. 继承性 4. 面向对象程序设计将描述事物的数据与 ( C ) 封装在一起,作为一个相互依存、不可分割的整体来处理。 A. 信息 B. 数据隐藏 C. 对数据的操作 D. 数据抽象 5. 关于面向对象方法的优点,下列不正确的叙述是(C )。 A. 与人类习惯的思维方法比较一致 B. 可重用性好 C. 以数据操作为中心 D.可维护性好 6.用例之间的关系不包括以下哪种关系?D A.泛化 B.包含 C. 扩展 D. 聚集和组合 7.顺序图中不包括以下哪种元素?(A) A.用例 B. 对象 C. 生命线 D. 消息

8. 用例图中不包括以下哪种元素?(B) A. 用例 B. 类 C. 参与者 D. 关联 9. 继承机制的作用是 ( C )。 A. 信息隐藏 B. 数据封装 C. 派生新类 D. 数据抽象 10. 面向对象方法学中,对象之间仅能通过(C )相联系。 A. 类 B.抽象 C. 消息 D. 封装 11. 脚本与用例之间的关系类似与(A)之间的关系。 A. 对象与类 B. 参与者与用例 C. 顺序图和抽象类 D. 消息和对象 12. 下列元素中,(D )不属于消息的组成。 A. 提供服务的对象 B. 服务 C. 输入信息 D. 事件 13. ( D )描述了一组交互对象间的动态协作关系,它表示完成某项行为的对象和这些对象之间传递消息的时间顺序。 A.对象图 B. 协作图 C. 状态图 D. 顺序图 14. ( D)是从用户使用系统的角度描述系统功能的图形表达方法。 A. 类图 B. 对象图 C. 序列图 D. 用例图 15. ( C ) 是表达系统的类及其相互联系的图示,它是面向对象设计的核心,建立状态图、协作图和其他图的基础。

Java面向对象16种设计原则

一类的设计原则 1依赖倒置原则-Dependency Inversion Principle (DIP) 2里氏替换原则-Liskov Substitution Principle (LSP) 3接口分隔原则-Interface Segregation Principle (ISP) 4单一职责原则-Single Responsibility Principle (SRP) 5开闭原则-The Open-Closed Principle (OCP) 二包的设计原则 6重用发布等价原则-Release ReuseEquivalency Principle (REP) 7无环依赖原则-The AcyclicDependencies Principle (ADP) 8稳定依赖原则-The StableDependencies Principle (SDP) 9稳定抽象等价原则-The StableAbstractions Principle (SAP) 10共同封闭原则-The CommonClosure Principle (CCP) 11全部重用原则-The Common Reuse Principle (CRP) 三扩展原则 12 迪米特法则-Least Knowledge Principle (LKP) 13 黑盒原则-BBP(Black Box Principle) 14 缺省抽象原则-DAP(Default Abstraction Principle) 15 接口设计原则-IDP(Interface Design Principle) 16 不要构造具体的超类原则-DCSP(Don't Concrete SupperclassPrinciple) 1. Dependency Inversion Principle (DIP) - 依赖倒置原则 依赖:在程序设计中,如果一个模块a使用或调用了另一个模块b,我们称模块a依赖模块b。高层模块与低层模块:往往在一个应用程序中,我们有一些低层次的类,这些类实现了一些基本的或初级的操作,我们称之为低层模块;另外有一些高层次的类,这些类封装了某些复杂的逻辑,并且依赖于低层次的类,这些类我们称之为高层模块。 依赖倒置原则的2个重要方针: A. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象 B. 抽象不应该依赖于细节,细节应该依赖于抽象 为什么叫做依赖倒置(Dependency Inversion)呢? 面向对象程序设计相对于面向过程(结构化)程序设计而言,依赖关系被倒置了。因为传统的结构化程序设计中,高层模块总是依赖于低层模块。

设计模式的六大原则实例

一、设计模式的六大原则 1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。开闭原则是面向对象的可复用设计的第一块基石。 开闭原则的关键是抽象化。 2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 面向对象的设计关注的是对象的行为,它是使用“行为”来对对象进行分类的,只有行为一致的对象才能抽象出一个类来。我经常说类的继承关系就是一种“Is-A”关系,实际上指的是行为上的“Is-A”关系,可以把它描述为 “Act-As”。 3、依赖倒转原则(Dependence Inversion Principle) 这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle) 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

相关文档