`
dftwilson
  • 浏览: 22381 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

软件架构设计--“层间解耦和API接口设计”

阅读更多
1 软件架构设计之“层间解耦和API接口设计” 
1)北向接口设计本质就更大系统的架构设计的一部分。
2)接口设计需要解决耦合与依赖的问题,系统间接口更是如此。
3)接口与实现分离、控制反转、依赖倒置是实现层间解藕的几个方式。

=======================
软件架构设计之“层间解耦和API接口设计”
                                                 钟振 00112298,2013-11-11
2 1      概述
“分层模式”是一种最常用的软件架构设计模式,采用分层模式时,要求层间低耦合,并且一般要求上层可调用下层服务、但不允许下层调用上层。那么当系统有这种需求(下层调用上层)时,应该如何设计呢?
本文主要参考[1] 文章,保留最精华的内容、补充部分方法和自己的理解、忽略“依赖注入”(有点晦涩),可结合[1]阅读本文。
其中“下层调用上层”的需求主要在“控制反转”一节给出解决方案。

3 2      接口和实现分离
4 2.1      面向过程的实现:函数库(函数调用)

5 2.2      面向对象的实现:类库(聚合关系)

6 3      依赖倒置(Dependency Inversion Principle)
7 3.1      原则说明
第一种描述([3]):
A. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。
  B. 抽象不能依赖于具象,具象依赖于抽象。
第二种描述:
       要针对接口编程,不要针对实现编程
8 3.2      解决方法一:类库设计者定义抽象接口(下层定义接口并实现)
当类库设计者难以和客户深入合作时,或者类库同时提供给很多客户使用时,这种方式比较合适。

9 3.3      解决方法二:调用方定义抽象接口(上层定义接口、下层实现)
如果是同一系统内的设计,优先使用方法二。这种方法也是面向对象设计推荐的方法。
10 3.3.1        Martin Flower给的例子

通常三层架构如上图(a);
经常需要引入一个Mapper层用于Domain/DB之间解耦具体数据映射方式,因此Mapper要依赖于Domain/DB,如(b)图;
但是,Domain怎么读写数据到DB呢?如果Domain依赖于Mapper则出现了“循环依赖”,这是一种很不好的设计。

由Domain层定义一个 Mapper Interface 接口,由Database层实现这个接口,则可以解决上述问题。

如果想简化类设计,可以把接口直接合入Domain层中(上图是合入Store类)。
11 3.3.2        Robert Martin给的例子
下图是一个典型的三层设计模式:

下图是经过依赖倒置重构后的架构:

12 4      控制反转
13 4.1      一个反面的例子

这是一个典型的双向依赖关系。这种双向依赖关系有一个非常严重的缺陷:由于GUI框架调用了应用程序中的某个特定函数(MyWindowProc), GUI框架根本无法独立存在;换一个新的应用程序,GUI框架多半就要做相应的修改。
14 4.2      解决方法一:面向过程设计中的“回调函数机制”

15 4.3      解决方案二:面向对象设计中的“模板方法模式”
16 4.3.1        王咏武给的例子

17 4.3.2        Craig Larman给的例子

18 4.4      解决方案三:面向对象设计中的“观察者模式”
19 4.4.1        Craig Larman给的例子

20 4.5      解决方案四:嵌入式软件中的“中断模式”
通过硬件中断主动上报事件,具体例子略。
21 5      参考资料
[1] 王咏武,《向依赖关系宣战——依赖倒置、控制反转和依赖注入辨析》,《程序员》杂志2005年1月
[2] Martin Flower,《Reducing Coupling》,2001,http://www.martinfowler.com/ieeeSoftware/coupling.pdf‎
[3] Robert Martin,《Agile Principles, Patterns, and Practices in C#》,2006
[4] Craig Larman,《Applying UML and Patterns》,2004

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics