4.考虑一下,上面的需求可能会变化的情况,比如可能会增加减少要调节的项目,每个调节项目调节时触发的动作会修改,代码要能够很方便扩展。请采用适合的设计模式解决
首先,根据题目要求,按下不同的按钮,调节不同的项目,这可以使用状态模式来实现。具体来说,按钮按下相当于切换了状态,在不同的状态下具有不同的行为,如色彩状态调节色彩,亮度状态调节亮度。
其次,要求每个项目对应的算法可以调节,比如说色彩调节可以有3种算法来实现,而可能根据不同情况选择不同算法。这里就其实就是算法的封装,采用策略模式。结构图如下:
状态相关代码:
package com.wbp.designmodelpractice2;
import android.widget.TextView;
// 抽象状态类
abstract class ButtonState {
protected int progress = 50;// 滑动条位置
protected AdjustAlgo adjustAlgo; // 算法类
// 算法开始执行
abstract public void beginAdjust();
// 更新状态(包含算法执行)
abstract public void update();
public void setAdjustAlgorithm(AdjustAlgo adjustAlgo) {
this.adjustAlgo = adjustAlgo;
}
public void setProcess(int progress) {
this.progress = progress;
}
public AdjustAlgo getAdjustAlgo() {
return adjustAlgo;
}
public int getProcess() {
return progress;
}
}
// 亮度调节状态类:具体状态
class LumState extends ButtonState {
TextView tv;
// 后期可能还会添加其他状态相关组件 如 ImageView
@Override
public void beginAdjust() {
// TODO Auto-generated method stub
adjustAlgo.excute(progress);
}
@Override
public void update() {
// TODO Auto-generated method stub
tv.setText(String.valueOf(progress));
beginAdjust();
}
}
// 色彩调节状态类:具体状态
class ColorState extends ButtonState {
TextView tv;
// 后期可能还会添加其他状态相关组件 如 ImageView
@Override
public void beginAdjust() {
// TODO Auto-generated method stub
adjustAlgo.excute(progress);
}
@Override
public void update() {
// TODO Auto-generated method stub
tv.setText(String.valueOf(progress));
beginAdjust();
}
}
// 饱和度调节状态类:具体状态
class SaturaState extends ButtonState {
TextView tv;
// 后期可能还会添加其他状态相关组件 如 ImageView
@Override
public void beginAdjust() {
// TODO Auto-generated method stub
adjustAlgo.excute(progress);
}
@Override
public void update() {
// TODO Auto-generated method stub
tv.setText(String.valueOf(progress));
beginAdjust();
}
}算法相关代码:
package com.wbp.designmodelpractice2;
// 抽象算法类
abstract public class AdjustAlgo {
abstract public void excute(int progress);
}
//抽象算法类
abstract class ColorAdjustAlgo extends AdjustAlgo{
abstract public void excute(int progress);
}
//抽象算法类
abstract class LumAdjustAlgo extends AdjustAlgo{
abstract public void excute(int progress);
}
//抽象算法类
abstract class SaturaAdjustAlgo extends AdjustAlgo{
abstract public void excute(int progress);
}
// 色彩调节算法类:具体算法
class ColorAdjustAlgoOne extends ColorAdjustAlgo {
public void excute(int progress) {
// 具体色彩调节算法
System.out.println("色彩--------------->算法 1");
}
}
// 色彩调节算法类:具体算法
class ColorAdjustAlgTwo extends ColorAdjustAlgo {
public void excute(int progress) {
// 具体色彩调节算法
System.out.println("色彩--------------->算法 2");
}
}
// 亮度调节算法类:具体算法
class LumAdjustAlgoOne extends AdjustAlgo {
public void excute(int progress) {
// 具体亮度调节算法
System.out.println("亮度--------------->算法 1");
}
}
// 亮度调节算法类:具体算法
class LumAdjustAlgoTwo extends AdjustAlgo {
public void excute(int progress) {
// 具体亮度调节算法
System.out.println("亮度--------------->算法 2");
}
}
// 饱和度调节算法类:具体算法
class SaturaAdjustAlgoOne extends AdjustAlgo {
public void excute(int progress) {
// 具体饱和度调节算法
System.out.println("饱和度--------------->算法 1");
}
}
// 饱和度调节算法类:具体算法
class SaturaAdjustAlgoTwo extends AdjustAlgo {
public void excute(int progress) {
// 具体饱和度调节算法
System.out.println("饱和度--------------->算法 2");
}
}package com.wbp.designmodelpractice2;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
SeekBar seekbar;
Button btnLum;
Button btnColor;
Button btnSatura;
TextView tvLum;
TextView tvColor;
TextView tvSatura;
List<ButtonState> stateList = new ArrayList<ButtonState>(); //
ButtonState state;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
// 界面初始化
seekbar = (SeekBar) findViewById(R.id.seekBar1);
seekbar.setProgress(50);
btnLum = (Button) findViewById(R.id.btnLum);
btnLum.setTag(0);
btnLum.setOnClickListener(this);
btnColor = (Button) findViewById(R.id.btnColor);
btnColor.setTag(1);
btnColor.setOnClickListener(this);
btnSatura = (Button) findViewById(R.id.btnSatura);
btnSatura.setTag(2);
btnSatura.setOnClickListener(this);
// 新建所有状态,并设置其对应的算法
LumState lum = new LumState();
lum.tv = (TextView) findViewById(R.id.tvLum);
lum.setAdjustAlgorithm(new LumAdjustAlgoOne());
stateList.add(lum);
ColorState color = new ColorState();
color.tv = (TextView) findViewById(R.id.tvColor);
color.setAdjustAlgorithm(new ColorAdjustAlgoOne());
stateList.add(color);
SaturaState satura = new SaturaState();
satura.tv = (TextView) findViewById(R.id.tvSatura);
satura.setAdjustAlgorithm(new SaturaAdjustAlgoTwo());
stateList.add(satura);
state = (ButtonState) stateList.get(0);
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
// 应用算法
state.setProcess(progress);
state.update();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
state = (ButtonState) stateList.get((Integer) arg0.getTag());
seekbar.setProgress(state.getProcess());
state.update();
}
}
1、扩展项目只需要增加新的状态类即可,扩展项目对应的算法只需要增加新的算法类即可,扩展很方便,完全符合“开闭”原则。这里有一点要说明的是,扩展项目的时候不一定像本题这样只通过TextView来显示项目数值,实际很可能还要显示别的组件,比如说显示颜色块,能让人直观的感受颜色变化。这一点通过状态类的扩展也容易做到。
2、标准的状态模式增加新的状态类需要修改负责状态转换的源代码,所以对“开闭”原则的支持并不好,这里巧妙的采用了Button点击来切换状态,解决了这个问题。
3、关于设计模式的选择:刚接触到这个题目的时候看到项目和算法两个维度的变化,感觉应该用桥接模式。但是自己思考过后,认为用在这里并不恰当。桥接模式两个维度分别有M、N种变化,那么总变化数为M*N,而且这M*N种变化都有存在的意义。但是本题目不是这样的,比如说,将颜色算法用到亮度状态上,结果显然是不伦不类的。
4、关于设计模式的体会:其实23中设计模式也只是相当于一些例子罢了,最重要的还是面向对象设计的那7个设计原则。开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段。对于如何编写扩展性好的程序,我的经验是,类和接口的设计要功能简单,然后编程的时候针对接口编程,这样就很容易符合“开闭”原则了。
1、最近看到很多设计模式采用 配置文件+反射机制 ,扩展只需要增加相关类,修改配置文件即可,客户端完全不需要改动。感觉这也太牛了吧!!千方百计想用在本例中,但是最终还是做不到。最起码按钮以及按钮的响应得添加吧,这些内容的添加难道可以不修改客户端吗?求解啊%>_<%
2、感觉设计的并不好,希望路过的高人不吝赐教
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/a_txpt_001/article/details/46760639