By 高焕堂 2013/09/03
亲自设计<通用性接口>
1. 复习:通用性接口设计
首先,看看一个Client/Server结构:
兹增添一个EIT造形,[ 认识EIT造形 ] 如下:
此EIT造形的内部结构,如下:
EIT造形有两种主要变形,兹采取另一个变形,上图就相当于:
这个<E>可提供一个接口<IE>给Client来使用,上图也相当于下图:
基于此架构,兹再增添一组Client-2/Server-2结构,他们共享同一组<E&I>了;此<I>和<IE>就成为通用性接口了。如下图:
其中的 {Client-1, T1, Server-1} 与 {Client-2, T2, Server-2} 都可独立开发,只是共享<IE>和<I>通用性接口而已。这种独立性,可搭配敏捷迭代过程而独立开发与产出。亦即,{Client-1, T1, Server-1} 与 {Client-2, T2, Server-2} 可各归属于不同跌代的开发&产出标的。
2. 设计各”用例”(Use Case)共享的接口
用例(Use Case)常常用来分析和收集用户需求(Requirement),并表述于用例图(Use Case Diagram)和用例叙述(Use Description)文件里。由于一个用例就是系统提供给用户的一项完整服务(Service),其幕后隐藏了一个<I>。那么,一群用例就能共享一个通用性<I>了。于是,将用例内涵与上图的基本架构结合起来了。就成为下图:
此架构图展现了两个优越的特性:
- 各组用例之间都是独立的。例如,{UseCase-1, UC1_Plugin} 与 {UseCase-2, UC2_Plugin} 两者是独立的,可以分别归属于不同跌代的工作产出目标。虽然各组用例共享了通用性接口,但都能用有自己的特殊性接口。
- 透过EIT造形的转换接口之后,Client部分与Server部分是独立的,创造了两端各自的变动自由度。例如,UseCase-1的UI画面的改变,不会受制于MediaPlayer的接口(函数);此外,MediaPlayer的接口改变了,只需改变UC1_Plugin,而不会波及各UseCase-1或UseCase-2等。
接着,还可以添加上曹操类(Stub),它能将通用性的<I>,转换成特殊性的接口。如下图:
之后,基于此项结构,UseCase个数都可以无限增加,而且都透过通用性的IPlugin接口的exectute()函数和Plugin类的onExecute()函数来做为通信渠道。于是,实现了各用例的通用性接口设计了,也落实用户的需求了。
3. 应用程序(App)范例:<播放MP3音乐>
兹绘制其用例图,如下:
从这用例图里,可以看出来,这个App包含有两个用例:
- UC-001:播放(Play)音乐。
- UC-002:播放(Play)某首音乐。
从上图可以看到,用例之间有两种关系,分别是「包含」(include)和扩充(extend)关系。
4. 以IPugin通用性接口实践<UC-001>
4.1 架构设计
此范例展示如何建立一个框架(Framework):包含一个IPlugin接口和一个Plugin基类。由它来提供统一的通信接口,来整合各敏捷跌代过程中所开发的各用例代码。例如,在敏捷的第1回跌代时,可先产出UC-001部分,其架构图为:
前面已经提到过,这项架构设计的优点是:
- 各组用例之间都是独立的,可做为不同跌代的工作产出目标。
- 虽然各组用例共享了通用性接口,但都能用有自己的特殊性接口。
- 透过EIT造形的转换接口之后,Client部分与Server部分是独立的,创造了两端各自的变动自由度。例如,UseCase-1的UI画面的改变,不会受制于MediaPlayer的接口(函数);此外,MediaPlayer的接口改变了,只需改变UC1_Plugin,而不会波及各UseCase-1或UseCase-2等。
- 掌握框架者,就能掌控一切。例如,可以在Plugin基类的幕后,可设计一只看门狗(Watch Dog)来监控各Use Case的通信。则框架主人透过统一接口的制定,来达到全面监控的目标。
4.2 UI画面设计
由于EIT造形的转换接口,Use Case的Client部分与Server部分是独立的,创造了两端各自的变动和成长自由度。首先,敏捷地设计了简单的UI画面如下:
按下<play>按钮,就会播放预设(Default)的MP3音乐,按下<stop>就停只播放,按下<exit>就结束此程序了。 [歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
4.3 Android开发项目
在Android平台上来实践上述范例的架构,兹建立Android开发项目(Project)如下:
==> 代码范例
5. 以IPugin通用性接口实践<UC-002>
5.1 架构设计
在刚才的范例(一)里,已經建立了一个框架,提供统一的接口来整合各UseCase实现代码。现在,基于此项架构,可以继续开发更多的UseCase,它们都透过通用性的IPlugin接口的exectute()函数和Plugin类的onExecute()函数来做为通信渠道。于是,实现了各用例的通用性接口设计了,也实现了多用例的目标。例如,可以增添新的UseCase-2,如下图:
5.2 UI画面设计
由于EIT造形的转换接口,Use Case的Client部分与Server部分是独立的,创造了两端各自的变动和成长自由度。首先,敏捷地设计了简单的UI如下:
按下<music-01>按钮,就选择第01首MP3音乐,并开时播放。播放时,如果按下<stop>就停只播放。按下<music-02>按钮,就选择第02首MP3音乐,并开时播放,此时如果按下<stop>就停只播放。若按下<exit>就结束此程序了。[歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
5.3 Android开发项目
在Android平台上来实践上述范例的架构,兹建立Android开发项目(Project)如下:
==> 代码范例
6. 结语
在UseCase-1里,其与Server的特殊性接口,包括有两项功能:
public void play()
{ ip.execute(0, R.raw.jp_song); }
public void stop()
{ ip.execute(1, -1); }
其将play()函数编号为0,并将stop()编号为1;然后调用通用性的IPlugin接口的execute()函数。而在UseCase-2里,其与Server的特殊性接口,包括有三功能:
public void play()
{ ip.execute(0, -1); }
public void stop()
{ ip.execute(1, -1); }
public void set_music(int song_id){
stop();
ip.execute(2, song_id);
play();
}
其将play()函数编号为0,将stop()编号为1,并将set_music()编号为2;然后调用通用性的IPlugin接口的execute()函数。所以UseCase-1、UseCase-2和UseCase-n都共享通用性接口,又能提供自己特殊化接口。基于其通用性接口,来整合众多的用例;同时,基于其特殊化接口,来满足各用例的特殊功能。◆
[Go Back]