By 高焕堂 2013/02/04
Use Case需求范例(二):实践<UC-002:播放(Play)某首音乐>
1. 架构设计
在刚才的范例(一)里,已經建立了一个框架,提供统一的接口来整合各UseCase实现代码。现在,基于此项架构,可以继续开发更多的UseCase,它们都透过通用性的IPlugin接口的exectute()函数和Plugin类的onExecute()函数来做为通信渠道。于是,实现了各用例的通用性接口设计了,也实现了多用例的目标。例如,可以增添新的UseCase-2,如下图:
2. UI画面设计
由于EIT造形的转换接口,Use Case的Client部分与Server部分是独立的,创造了两端各自的变动和成长自由度。首先,敏捷地设计了简单的UI如下:
按下<music-01>按钮,就选择第01首MP3音乐,并开时播放。播放时,如果按下<stop>就停只播放。按下<music-02>按钮,就选择第02首MP3音乐,并开时播放,此时如果按下<stop>就停只播放。若按下<exit>就结束此程序了。[歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
3. Android开发项目
在Android平台上来实践上述范例的架构,兹建立Android开发项目(Project)如下:
4. 代码范例: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);
}
5. 代码范例:App部分
// UC2_Stub.java类
package Service;
import Framework.Plugin;
public abstract class UC2_Stub extends Plugin {
private int curr_music;
@Override
protected boolean onExecute(int code, int arg) {
if(code == 0) play(curr_music); //播放目前音樂
else if(code == 1) stop(); //停止播放音樂
else if(code == 2) curr_music = arg; //設定目前音樂
return false;
}
public abstract void play(int arg);
public abstract void stop();
}
//
UC2_Plugin.java类
package Service;
import android.content.Context;
import android.media.MediaPlayer;
import android.util.Log;
public class UC2_Plugin extends UC2_Stub{
private MediaPlayer mPlayer = null;
private Context ctx;
public UC2_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;
}
}}
// MainActivity.java类
package com.example.cx02;
import Framework.IPlugin;
import Service.UC2_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, btn4;
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.leaf);
btn.setText("music_01"); btn.setOnClickListener(this);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(250, 100);
param.topMargin = 10; param.leftMargin = 10;
layout.addView(btn, param);
btn2 = new Button(this); btn2.setId(102);
btn2.setBackgroundResource(R.drawable.leaf2);
btn2.setText("music_02"); btn2.setOnClickListener(this);
layout.addView(btn2, param);
btn3 = new Button(this); btn3.setId(103);
btn3.setBackgroundResource(R.drawable.heart);
btn3.setText("stop"); btn3.setOnClickListener(this);
layout.addView(btn3, param);
btn4 = new Button(this); btn4.setId(104);
btn4.setBackgroundResource(R.drawable.heart);
btn4.setText("exit"); btn4.setOnClickListener(this);
layout.addView(btn4, param);
setContentView(layout);
//-------------------------------
ip = new UC2_Plugin(this);
}
public void onClick(View v) {
switch(v.getId()){
case 101: set_music(R.raw.jp_song); break;
case 102: set_music(R.raw.test_cbr); break;
case 103: stop(); break;
case 104: stop(); finish(); break;
}
}
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(); }
}
}
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]