码迷,mamicode.com
首页 > 其他好文 > 详细

实现类似美图秀秀里面的属性增强调节——设计模式练习

时间:2015-07-05 09:34:22      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:设计模式   android   

1.在界面下方有3个按钮,分别是亮度、色彩度、饱和度 
2. 点击按钮,选中一个,上面用一个滚动条显示亮度、色彩度、饱和度的值,三个用同一个滚动条。 
3.选中后,滑动滚动条,调节当前选择的亮度、色彩度、饱和度。(不用真调节相机,假实现即可,但需要考虑将来可能会实现,要预留实现接口) 

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、感觉设计的并不好,希望路过的高人不吝赐教技术分享



版权声明:本文为博主原创文章,未经博主允许不得转载。

实现类似美图秀秀里面的属性增强调节——设计模式练习

标签:设计模式   android   

原文地址:http://blog.csdn.net/a_txpt_001/article/details/46760639

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!