接口与接口设计原则

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

接口与接口设计原则
一.11种设计原则
1.单一职责原则- Single Responsibility Principle(SRP)
就一个类而言,应该仅有一个引起它变化的原因。

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

2.开放-封闭原则- Open Close Principle(OCP)
软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。

对于扩展是开放的,对于更改是封闭的. 关键是抽象.将一个功能的通用部分和实现细节部分清晰的分离开来。

开发人员应该仅仅对程序中呈现出频繁变化的那些部分作出抽象. 拒绝不成熟的抽象和抽象本身一样重要)
3.里氏替换原则- Liskov Substitution Principle(LSP)
1 / 77
子类型(subclass)必须能够替换掉它们的基类型(superclass)。

4.依赖倒置原则(IoCP) 或依赖注入原则- Dependence Inversion Principle(DIP)
抽象不应该依赖于细节。

细节应该依赖于抽象。

Hollywood原则: "Don't call us, we'll call you". 程序中所有的依赖关系都应该终止于抽象类和接口。

针对接口而非实现编程。

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

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

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

5.接口隔离原则(ISP)
不应该强迫客户依赖于它们不用的方法。

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

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

6.重用发布等价原则(REP)
重用的粒度就是发布的粒度。

2 / 77
7.共同封闭原则(CCP)
包(类库、DLL)中的所有类对于同一类性质的变化应该是共同封闭的。

一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。

8.共同重用原则(CRP)
一个包(类库、DLL)中的所有类应该是共同重用的。

如果重用了包(类库、DLL)中的一个类,
那么就要重用包(类库、DLL)中的所有类。

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

)
包(类库、DLL)耦合原则
9.无环依赖原则(ADP)
3 / 77
在包的依赖关系图中不允许存在环。

10.稳定依赖原则(SDP)
朝着稳定的方向进行依赖。

应该把封装系统高层设计的软件(比如抽象类)放进稳定的包中,不稳定的包中应该只包含那些很可能会改变的软件(比如具体类)。

11.稳定抽象原则(SAP)
包的抽象程度应该和其稳定程度一致。

一个稳定的包应该也是抽象的,一个不稳定的包应该是抽象的.
其它扩展原则
12.BBP(Black Box Principle)黑盒原则
多用类的聚合,少用类的继承。

4 / 77
13.DAP(Default Abstraction Principle)缺省抽象原则
在接口和实现接口的类之间引入一个抽象类,这个类实现了接口的大部分操作.
14.IDP(Interface Design Principle)接口设计原则
规划一个接口而不是实现一个接口。

15.DCSP(Don't Concrete Supperclass Principle)
不要构造具体的超类原则,避免维护具体的超类。

16.迪米特法则
一个类只依赖其触手可得的类。

5 / 77
二.类的设计原则
6 / 77
1.开闭原则
Software entities (classes, modules, function, etc.) should be open for extension, but closed for modification.
软件实体(模块,类,方法等)应该对扩展开放,对修改关闭。

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

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

根据开闭原则,在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)
7 / 77
的基础上,能扩展其功能(扩展开放)。

- 扩展开放:某模块的功能是可扩展的,则该模块是扩展开放的。

软件系统的功能上的可扩展性要求模块是扩展开放的。

- 修改关闭:某模块被其他模块调用,如果该模块的源代码不允许修改,则该模块修改关闭的。

软件系统的功能上的稳定性,持续性要求是修改关闭的。

这也是系统设计需要遵循开闭原则的原因:
1)稳定性。

开闭原则要求扩展功能不修改原来的代码,这可以让软件系统在变化中保持稳定。

2)扩展性。

开闭原则要求对扩展开放,通过扩展提供新的或改变原有的功能,让软件系统具有灵活的可扩展性。

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

8 / 77
开闭原则的实现方法
为了满足开闭原则的对修改关闭(closed for modification)原则以与扩展开放(open for extension)原则,应该对软件系统中的不变的部分加以抽象,在面向对象的设计中,
- 可以把这些不变的部分加以抽象成不变的接口,这些不变的接口可以应对未来的扩展;
- 接口的最小功能设计原则。

根据这个原则,原有的接口要么可以应对未来的扩展;不足的部分可以通过定义新的接口来实现;
- 模块之间的调用通过抽象接口进行,这样即使实现层发生变化,也无需修改调用方的代码。

接口可以被复用,但接口的实现却不一定能被复用。

接口是稳定的,关闭的,但接口的实现是可变的,开放的。

可以通过对接口的不同实现以与类的继承行为等为系统增加新的或改变系统原来的功能,实现软件系统的柔软扩展。

9 / 77
简单地说,软件系统是否有良好的接口(抽象)设计是判断软件系统是否满足开闭原则的一种重要的判断基准。

现在多把开闭原则等同于面向接口的软件设计。

开闭原则的相对性
软件系统的构建是一个需要不断重构的过程,在这个过程中,模块的功能抽象,模块与模块间的关系,都不会从一开始就非常清晰明了,所以构建100%满足开闭原则的软件系统是相当困难的,这就是开闭原则的相对性。

但在设计过程中,通过对模块功能的抽象(接口定义),模块之间的关系的抽象(通过接口调用),抽象与实现的分离(面向接口的程序设计)等,可以尽量接近满足开闭原则。

2.单一职责原则
前言
Robert C. Martin氏为我们总结了在面向对象的设计(OOD)中应该遵循的原则,这些原则被称为“Principles of OOD”,关于“Principles of OOD”的相关文章可以从Object Menter得到。

10 / 77
本文介绍“Principles of OOD”中的单一职责原则:Single Responsibility Principle (SRP)。

可以从这里查看Single Responsibility Principle (SRP)的原文。

概要
There should never be more than one reason for a class to change.
永远不要让一个类存在多个改变的理由。

换句话说,如果一个类需要改变,改变它的理由永远只有一个。

如果存在多个改变它的理由,就需要重新设计该类。

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

这也是单一职责原则的命名含义。

为什么一个类不能有多于一个以上的职责呢?
11 / 77
如果一个类具有一个以上的职责,那么就会有多个不同的原因引起该类变化,而这种变化将影响到该类不同职责的使用者(不同用户):
1,一方面,如果一个职责使用了外部类库,则使用另外一个职责的用户却也不得不包含这个未被使用的外部类库。

2,另一方面,某个用户由于某个原因需要修改其中一个职责,另外一个职责的用户也将受到影响,他将不得不重新编译和配置。

这违反了设计的开闭原则,也不是我们所期望的。

职责的划分
既然一个类不能有多个职责,那么怎么划分职责呢?
Robert.C Martin给出了一个著名的定义:所谓一个类的一个职责是指引起该类变化的一个原因。

12 / 77
If you can think of more than one motive for changing a class, then that class has more than one responsibility.
如果你能想到一个类存在多个使其改变的原因,那么这个类就存在多个职责。

Single Responsibility Principle (SRP)的原文里举了一个Modem的例子来说明怎么样进行职责的划分,这里我们也沿用这个例子来说明一下:
SRP违反例:
public interface Modem {
public void dial(String pno); //拨号
public void hangup(); //挂断
public void send(char c); //发送数据
13 / 77
public char recv(); //接收数据
}
咋一看,这是一个没有任何问题的接口设计。

但事实上,这个接口包含了2个职责:第一个是连接管理(dial, hangup);另一个是数据通信(send, recv)。

很多情况下,这2个职责没有任何共通的部分,它们因为不同的理由而改变,被不同部分的程序调用。

所以它违反了SRP原则。

下面的类图将它的2个不同职责分成2个不同的接口,这样至少可以让客户端应用程序使用具有单一职责的接口:
14 / 77
接口定义
具体类实现
让ModemImplementation实现这两个接口。

我们注意到,ModemImplementation又组合了2个职责,这不是我们希望的,但有时这又是必须的。

通常由于某些原因,迫使我们不得不绑定多个职责到一个类中,但我们至少可以通过接口的分割来分离应用程序关心的概念。

事实上,这个例子一个更好的设计应该是这样的,如图:
15 / 77
接口定义
具体类实现
小结
Single Responsibility Principle (SRP)从职责(改变理由)的侧面上为我们对类(接口)的抽象的颗粒度建立了判断基准:在为系统设计类(接口)的时候应该保证它们的单一职责性。

3接口分隔原则
前言
16 / 77
Robert C. Martin氏为我们总结了在面向对象的设计(OOD)中应该遵循的原则,这些原则被称为“Principles of OOD”,关于““Principles of OOD”的相关文章可以从Object Menter得到。

本文介绍“Principles of OOD”中的接口分隔原则:Interface Segregation Principle (ISP)。

可以从这里查看Interface Segregation Principle (ISP)的原文。

概要
Clients should not be forced to depend upon interfaces that they do not use.
不能强迫用户去依赖那些他们不使用的接口。

换句话说,使用多个专门的接口比使用单一的总接口总要好。

它包含了2层意思:
- 接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法塞进同一个接口里。

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

- 接口的依赖(继承)原则:如果一个接口a依赖(继承)另一个接口b,则接口a相当于继承了接口b的方法,那么继承了接口b后的接口a也应该遵循上述原则:不应该包含用户不使用的方法。

反之,则说明接口a被b给污染了,应该重新设计它们的关系。

如果用户被迫依赖他们不使用的接口,当接口发生改变时,他们也不得不跟着改变。

换而言之,一个用户依赖了未使用但被其他用户使用的接口,当其他用户修改该接口时,依赖该接口的所有用户都将受到影响。

这显然违反了开闭原则,也不是我们所期望的。

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

假如有一个Door,有lock,unlock功能,另外,可以在Door上安装一个Alarm而使其具有报警功能。

用户可以选择一般的Door,也可以选择具有报警功能的Door。

18 / 77
有以下几种设计方法:
ISP原则的违反例:
方法一:
在Door接口里定义所有的方法。

图:
19 / 77
但这样一来,依赖Door接口的CommonDoor却不得不实现未使用的alarm()方法。

违反了ISP原则。

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

20 / 77
跟方法一一样,依赖Door接口的CommonDoor却不得不实现未使用的alarm()方法。

违反了ISP原则。

遵循ISP原则的例:
方法三:通过多重继承实现
在Alarm接口定义alarm方法,在Door接口定义lock,unlock方法。

接口之间无继承关系。

CommonDoor
21 / 77
实现Door接口,
AlarmDoor有2种实现方案:
1),同时实现Door和Alarm接口。

2),继承CommonDoor,并实现Alarm接口。

该方案是继承方式的Adapter设计模式的实现。

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

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

方法四:通过委让实现
22 / 77
这种方法其实是委让方式的Adapter设计模式的实现。

在这种方法里,AlarmDoor实现了Alarm接口,同时把功能lock和unlock委让给CommonDoor对象完成。

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

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

4依赖倒置原则
Robert C. Martin氏为我们总结了在面向对象的设计(OOD)中应该遵循的原则,这些原则被称为“Principles of OOD”,关于“Principles of OOD”的相关文章可以从Object Menter得到。

本文介绍DIP:Dependency Inversion Principle - 依赖倒置原则。

有关Dependency Inversion Principle (DIP) 原文可以从这里得到。

该文提出了依赖倒置原则的2个重要方针:
24 / 77
A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
中文意思为:
A. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
B. 抽象不应该依赖于细节,细节应该依赖于抽象
概念解说:
依赖:在程序设计中,如果一个模块a使用/调用了另一个模块b,我们称模块a依赖模块b。

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

为什么叫做依赖倒置(Dependency Inversion)呢?
面向对象程序设计相对于面向过程(结构化)程序设计而言,依赖关系被倒置了。

因为传统的结构化程序设计中,高层模块总是依赖于低层模块。

问题的提出:
Robert C. Martin氏在原文中给出了“Bad Design”的定义:
1. It is hard to change because every change affects too many other parts of the system. (Rigidity)
系统很难改变,因为每个改变都会影响其他很多部分。

26 / 77
2. When you make a change, unexpected parts of the system break. (Fragility)
当你对某地方做一修改,系统的看似无关的其他部分都不工作了。

3. It is hard to reuse in another application because it cannot be disentangled from
the current application. (Immobility)
系统很难被另外一个应用重用,因为你很难将要重用的部分从系统中分离开来。

导致“Bad Design”的很大原因是“高层模块”过分依赖“低层模块”。

一个良好的设计应该是系统的每一部分都是可替换的。

如果“高层模块”过分依赖“低层模块”,一方面一旦“低层模块”需要替换或者修改,“高层模块”将受到影响;另一方面,高层模块很难可以重用。

27 / 77
比如,一个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(低层模块)
抽象接口是对低层模块的抽象,低层模块继承或实现该抽象接口。

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

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

Robert C. Martin氏给出的DIP方案的类的结构图:
PolicyLayer-->MechanismInterface(abstract)--MechanismLayer-->UtilityInterface(abstract)--Utility Layer
类与类之间都通过Abstract Layer来组合关系。

29 / 77
5里氏替换原则
Robert C. Martin氏为我们总结了在面向对象的设计(OOD)中应该遵循的原则,这些原则被称为“Principles of OOD”,关于“Principles of OOD”的相关文章可以从Object Menter得到。

本文介绍“Principles of OOD”中的里氏替换原则:Liskov Substitution Principle (LSP)。

可以从这里查看Liskov Substitution Principle (LSP)的原文。

里氏替换原则LSP的概念解说
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有引用基类的地方必须能透明地使用其子类的对象。

也就是说,只有满足以下2个条件的OO设计才可被认
30 / 77
为是满足了LSP原则:
- 不应该在代码中出现if/else之类对子类类型进行判断的条件。

以下代码就违反了LSP定义。

if (obj typeof Class1) {
do something
} else if (obj typeof Class2) {
do something else
}
- 子类应当可以替换父类并出现在父类能够出现的任何地方,或者说如果我们把代码中使用基类的地方用它的子类所代替,代码还能正常工作。

里氏替换原则LSP是使代码符合开闭原则的一个重要保证。

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

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

类的继承原则:
Robert C. Martin氏在介绍Liskov Substitution Principle (LSP)的原文里,举了Rectangle和Square的例子。

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

代码:
32 / 77
这里Rectangle是基类,Square从Rectangle继承。

33 / 77
这种继承关系有什么问题吗?
假如已有的系统中存在以下既有的业务逻辑代码:
void g(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
if (r.getWidth() * r.getHeight() != 20) {
throw new RuntimeException();
}
}
则对应于扩展类Square,在调用既有业务逻辑时:
34 / 77
Rectangle square = new Square();
g(square);
时会抛出一个RuntimeException异常。

这显然违反了LSP原则。

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

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

35 / 77
现在把前提条件以与后续条件应用到继承子类中,子类方法应该满足:
1)前提条件不强于基类.
2)后续条件不弱于基类.
换句话说,通过基类的接口调用一个对象时,用户只知道基类前提条件以与后续条件。

因此继承类不得要求用户提供比基类方法要求的更强的前提条件,亦即,继承类方法必须接受任何基类方法能接受的任何条件(参数)。

同样,继承类必须顺从基类的所有后续条件,亦即,继承类方法的行为和输出不得违反由基类建立起来的任何约束,不能让用户对继承类方法的输出感到困惑。

这样,我们就有了基于合同的LSP,基于合同的LSP是LSP的一种强化。

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

36 / 77
三.针对接口编程,而不是针对实现编程
在面向对象设计方法中有很多值得提倡的方法,这些方法可以为我们的设计带来很大的灵活性,可复用性。

其中一个原则就是“针对接口编程,而不是针对实现编程”
这个原则带来的好处有以下几点:
Client不必知道其使用对象的具体所属类。

Client无需知道特定类,只需知道他们所期望的接口。

一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换。

对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。

松散藕合(loosens coupling)。

37 / 77
增加了重用的可能性。

提高了(对象)组合的机率,因为被包含对象可以是任何实现了一个指定接口的类。

但从辩证法的角度看,事物总有利有弊。

“针对接口编程”有如上诸多好处,却不可避免的带来设计的复杂性。

特别对于没
有丰富经验的设计人员。

其中令我比较困惑的地方是:
要想针对接口编程,就必然要最大化接口类,使包括所有子类的方法,这样我们才能利用多态性用接口类来实现操作子类。

但这会带来以下几点不足。

违反面向对象的另一个原则,这个原则是:一个类只能定义那些对它的子类有意义的操作。

接口类包括了并不是对每一个子类都有意义的方法,使接口类臃肿,难以理解。

从父类继承的无用方法,如何处理。

敏捷开发提倡简单设计的实践,“并在实现新需求时抓住机会改进设计”以对同类性质的改动封闭,做到由需求的变化驱动设计的进
38 / 77
为设计的退化而责怪需求的变化),同时经验在此起到十分重要的作用,如有经验的设计人员可以凭经验在初始设计时做出必要的抽象来等,或是在需求变动时确定系统所需的抽象(所需的封闭),当然应与早的刺激这种变化的出现(如测试驱动的开发方法)。

OOD承诺了一系列的好处(灵活性可重用性可维护性),用OO语言设计开发,若要方便的得到这些所谓的好处,有一系列的原则SRP,OCP,LSP,ISP等。

SRP(单一职责原则)维护类的简单性,类不应承担一个以上令其变化的原因,否则应考虑分离并重新构造类,但如果的应用的变化类中的职责同时变化,却没必要分离他们
Ocp(开闭原则)使OO系统做到对扩展开放,对修改封闭。

OCP的遵循关键在于抽象,其主要实现方式有:定义接口描绘所需的操需关注接口的调用,子类型可以以任何其选择的方式实现接口,即所谓的stategy模式,或者定义抽象类并于其中实现公共操作,个性操作定或virtual,由子类型负责个性化实现,通过此两法,将功能的通用部分和实现细节分离出来。

当然,设计人员应该确定(猜测或凭经验)化做到封闭,因为不可能对所有变化做到封闭,如《敏捷模式实践》中提到shape类型排序处理问题,为做到对排序安排(或变动)的封类型间无需相互知晓,也可以做到自由安排排序顺序),选择使用“数据驱动”的方式(即单独构造结构表示排序安排—其中以子类类型
39 / 77
位置表先后),于shape基类中实现一次Precedes操作即可,子类型无需分别实现。

OCP作为OOD核心所在依赖抽象来实现,但敏捷好的设计)拒绝不成熟的抽象,程序仅应对频繁变化的部分做出抽象。

Liskov替换原则是使得ocp成为可能的原则之一,强调“子类型subtype必须能够替换掉它们的基类型basetype”,控制OO的在OOD用is-a来确定类间的继承关系,LSP指出这种is-a关系是就行为方式(即类的各操作)而言的,而行为方式是可以合理假设的依赖的。

为遵循LSP,可借用DBC(design by contract)的操作前置条件和后置条件,“要使操作得以执行,前置条件必须为真,执作要确保后置条件为真”(为每个方法注明其前置和后置条件十分有帮助),如此,则“在重新声明派生类中操作时,只能使用相等或更来替换原始的前置条件,只能用相等或更强的后置条件来替换原始的后置条件”(interface和其实现类间抽象方法和其实现此二者一定同时亦可用前述ocp遵循所用的二模式使设计符合LSP,另外子类型中的异常抛出应考虑在遵循LSP的范围内。

关于提取公共部分的设计工具:“提取公共职责放入超类中,稍后添加的新的子类型可能会以新的方式支持同样的职责,此时原来的个抽象类”。

DIP(依赖倒置原则),作为framework的设计核心,其相对于传统软件设计而言,通常(传统)软件设计中采用结构化设计用高层模
40 / 77
模块,这样高层模块将严重依赖于底层模块的变动,在OOD中通过为高层模块定义所需使用的服务接口,底层模块现实这样的接口,高接口使用下一层(strategy模式所声明的),如此看来接口的拥有者一般是其使用者而非其实现者。

通常为了满足DIP-良好OOD的基本么需要找出系统中潜在的抽象,而抽象通常是那些不随具体细节变化而变化的东东。

ISP接口隔离原则,如SRP维护类的简单性一样,ISP用于维护接口的简单和必要性,因为接口是为客户调用的,因此其应该是“大小“胖”接口显然对调用者造成累赘,ISP则用于将“胖”接口分离成多个合适的接口。

当然,在系统设计实现中要做到这些并非容易,单单知道其存在未必做得到将其实现到系统中,开发经验的积累同样重要,但早些知道做时将其考虑进去,也是积累,慢慢来吧,n多事要做呐。

41 / 77。

相关文档
最新文档