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

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

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

时间: 2024-12-27 23:51:04

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

类似美图秀秀的自由拼图功能是怎么实现的?

============问题描述============ 重写imageview..但不晓得为何我重写后只能显示一张图片,其余的还是不显示? ============解决方案1============ 不同格子的形式可以定义一个VIEW,最后把整个组合成一个IMAGE ============解决方案2============ 其实全部功能都能在同一个View里完成,用一个ArrayList记录所有的图片及其相关信息(例如位置,旋转角度等,写一个队列去记录即可),onTouch事件每次Actio

强大的Core Image(教你做自己的美图秀秀))

iOS5新特性:强大的Core Image(教你做自己的美图秀秀)) iOS5给我们带来了很多很好很强大的功能和API.Core Image就是其中之一,它使我们很容易就能处理图片的各种效果,色彩啊,曝光啊,饱和度啊,变形啊神马的.可惜苹果一直没能完善官方文档,也没有推出示例代码,所以国内很多同学可能还没有开始使用.但国外的大神们已经证明这是个相当强悍的框架,不仅功能强大,而且可以直接使用GPU,效率奇高,甚至可以实时的对视频进行渲染.下面让我们来看看,如何具体使用它:首先你需要导入 CoreI

利用Photos 框架搭建美图秀秀相册选择器

简介:Photos框架是iOS8.0后推出的一个新的用于对系统相册进行相关操作的,在iOS8.0之前,开发中只能使用AssetsLibrary框架来访问移动设备的图片库.本文中不再对AssetsLibrary做过多的介绍,仅针对Photos框架进行详细介绍.并且以美图秀秀的照片选择器作为实例载体进行功能实现. 首先要获取系统的所有相册,有多个方法可以选择 1.该方法通过唯一标识符identifiers来获取相册  PHFetchOptions为将要获取到了相册的相关属性对象 + (PHFetch

iOS开发系列--打造自己的“美图秀秀”

http://www.cnblogs.com/kenshincui/p/3959951.html#overview --绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益于它强大的开发框架.今天我们将围绕iOS中两大图形.图像绘图框架进行介绍:Quartz 2D绘制2D图形和Core Image中强大的滤镜功能. Quartz 2D 基本图形绘制 视图刷新 其他图形上下文 Core Image Quartz 2D 在iOS中常用的绘图框

美图秀秀滤镜之亮度调整

图像的亮度, 指的是图像像素的强度, 黑色为最暗, 白色为最亮, 在ios中黑色用0来表示, 白色用1来表示.一个像素, 基本上是用RGB三个颜色分量来表示的. R(0-1), G(0-1),B(0-1). 亮度调整有多种计算方法,效果并不完全相同,在颜色的表示方法中, HSL(L)表示法就是:色相(hue).饱和度(saturation).亮度(lightness),改变其中的L值就可以调整图象的亮度,但效果显得比较生硬. PhotoShop和GPUImage中采用的就是另外一种方法就是把图象

打造自己的“美图秀秀”

概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益于它强大的开发框架.今天我们将围绕iOS中两大图形.图像绘图框架进行介绍:Quartz 2D绘制2D图形和Core Image中强大的滤镜功能. Quartz 2D 在iOS中常用的绘图框架就是Quartz 2D,Quartz 2D是Core Graphics框架的一部分,是一个强大的二维图像绘制引擎.Quartz 2D在UIKit中也有很好的封装和集成,我们日常开发时所用到的UIKit中的组件都是由Cor

美图秀秀 web开发图片编辑器

美图秀秀web开发平台 http://open.web.meitu.com/wiki/ 1.环境配置 1.1.设置crossdomain.xml 下载crossdomain.xml文件,把解压出来的crossdomain.xml文件放在您保存图片或图片来源的服务器根目录下,比如: http://example.com.cn,那么crossdomain.xml的路径为:http://example.com.cn/crossdomain.xml.需要注意的是crossdomain.xml必须部署于站

Core Image 制作自己的美图秀秀

一.Core Image是和啥? 关于这个问题不太好回答,但其实又也很简单.肯定是苹果推出的关于图片处理的API.网上各路大神都有解释过,不过能看明白的不多,我的理解就是Photoshop的滤镜,当然在各种美图软件里都有这个功能,咱主要看怎么用吧 二.Core Image提供了哪些可用的滤镜呢? 127 values { [0] = "CIAccordionFoldTransition" [1] = "CIAdditionCompositing" [2] = &qu

美图秀秀-美化图片之【特效】界面设计

本文是特效界面设计,在美图秀秀的特效模块主要是实现图片添加滤镜效果,界面挺炫的. 界面包含黑边和虚化按钮,4种类型的滤镜,每种类型又包含许多具体滤镜效果,当我们点击时候开始处理图片 1.加载图片 self.imageView = [[UIImageView alloc] initWithImage:self.image]; self.imageView.frame = CGRectMake(0, 0, WIDTH, HEIGHT - 130); self.imageView.contentMod