By 高焕堂 2013/02/04
Use Case需求范例(一):实践<UC-001:播放(Play)音乐>
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的通信。则框架主人透过统一接口的制定,来达到全面监控的目标。
2. UI画面设计
由于EIT造形的转换接口,Use Case的Client部分与Server部分是独立的,创造了两端各自的变动和成长自由度。首先,敏捷地设计了简单的UI画面如下:
按下<play>按钮,就会播放预设(Default)的MP3音乐,按下<stop>就停只播放,按下<exit>就结束此程序了。 [歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
3. Android开发项目
在Android平台上来实践上述范例的架构,兹建立Android开发项目(Project)如下:
代码范例:Framework部分
// IPlugin.java接口
package Framework;
public interface IPlugin{
boolean execute(int code, int arg);
}
// Plugin.java类
package Framework;
public abstract class Plugin implements IPlugin{
@Override public boolean execute(int code, int arg) {
return onExecute(code, arg);
}
protected abstract boolean onExecute(int code, int arg);
}
代码范例:App部分
// UC1_Stub.java类
package Service;
import Framework.Plugin;
public abstract class UC1_Stub extends Plugin {
@Override protected boolean onExecute(int code, int arg) {
if(code == 0) play(arg); //播放目前音樂
else if(code == 1) stop(); //停止播放
return false;
}
public abstract void play(int arg);
public abstract void stop();
}
这曹操类的主要任务是:
- 实现了天子的接口,也就是onExecute()抽象函数。
- 提供了自己的新接口,也就是play()和stop()两个函数。
// UC1_Plugin.java类
package Service;
import android.content.Context;
import android.media.MediaPlayer;
import android.util.Log;
public class UC1_Plugin extends UC1_Stub{
private MediaPlayer mPlayer = null;
private Context ctx;
public UC1_Plugin(Context context){ ctx = context; }
@Override public void play(int arg) {
if(mPlayer != null) return;
mPlayer = MediaPlayer.create(ctx, arg);
try { mPlayer.start();
} catch (Exception e) { Log.e("StartPlay", "error: " + e.getMessage(), e); }
}
@Override public void stop() {
if (mPlayer != null) {
mPlayer.stop(); mPlayer.release(); mPlayer = null;
}
}}
这个App类(及子民类)只需要实现曹操的接口就行了,也就是实现play()和stop()函数。
// MainActivity.java类
package com.example.cx01;
import Framework.IPlugin;
import Service.UC1_Plugin;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements OnClickListener {
private Button btn, btn2, btn3;
private IPlugin ip;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn = new Button(this); btn.setId(101);
btn.setBackgroundResource(R.drawable.paint);
btn.setText("play"); btn.setOnClickListener(this);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(150, 75);
param.topMargin = 10; param.leftMargin = 10;
layout.addView(btn, param);
btn2 = new Button(this); btn2.setId(102);
btn2.setBackgroundResource(R.drawable.heart);
btn2.setText("stop"); btn2.setOnClickListener(this);
layout.addView(btn2, param);
btn3 = new Button(this); btn3.setId(103);
btn3.setBackgroundResource(R.drawable.heart);
btn3.setText("exit"); btn3.setOnClickListener(this);
layout.addView(btn3, param);
setContentView(layout);
//-------------------------------
ip = new UC1_Plugin(this);
}
public void onClick(View v) {
switch(v.getId()){
case 101: play(); break;
case 102: stop(); break;
case 103: stop(); finish(); break;
}
}
public void play(){ ip.execute(0, R.raw.jp_song); }
public void stop(){ ip.execute(1, -1); }
}
[Go Back]