您的位置:首页 > 编程语言 > Java开发

Java Design Demo--策略模式 (图片滤镜小工程)

2012-12-29 18:10 861 查看
●首先提出一个功能实现,思考自己平时的代码怎么写

●然后用设计模式重构。寻找优缺点。

●反思这么写是不是多人配合更好了,扩展性强了,面向对象,体现解耦性............?

●反思该设计模式应用场景。使用范围。

本文代码示例下载地址:http://download.csdn.net/detail/b275518834/4942096


策略模式的结构

策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一 个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

●精髓:一个对象一个行为

●写一个工具类 将字符串大写输出 将字符串小写输出 将字符串按空格分割输出 你大概会这么写

A例子

import java.util.Arrays;

public class MainDemo1 {

public static void main(String[] args) {
String s =
"Disagreement with beliefs is by definition incorrect";
System.out.println(s);
System.out.println(MainDemo1.toSplitter(s));
System.out.println(MainDemo1.toDowncase(s));
System.out.println(MainDemo1.toUpcase(s));
}

public static Object toSplitter(String str) {
return Arrays.toString(str.split(" "));
}

public static Object toDowncase(String str) {

return str.toLowerCase();

}

public static Object toUpcase(String str) {

return str.toUpperCase();

}
}


以下代码摘自《Java编程思想 ThanksInJava》策略模式

B例子

package interfaces.classprocessor;

import java.util.Arrays;

/**
* 策略模式 创建一个能够根据所传递的参数对象的不同而具有的不同行为的方法
* */
class Processor {

public String name() {
return getClass().getSimpleName();
};

Object process(Object input)
{
return input;

}
}

class Upcase extends Processor {
String process(Object input) {
return "大写输出:"+((String) input).toUpperCase();
}
}

class Downcase extends Processor {
String process(Object input) {
return "小写输出:"+((String) input).toLowerCase();
}
}

class Splitter extends Processor {
String process(Object input) {
return "分割输出:"+Arrays.toString(((String) input).split(" "));
}
}

public class Apply {
public static void process(Processor p, Object s) {
System.out.println("Using Processor " + p.name());
System.out.println(p.process(s));
}

public static String s = "Disagreement with beliefs is by definition incorrect";

public static void main(String[] args) {
process(new Upcase(), s);
process(new Downcase(), s);
process(new Splitter(), s);
}

}


策略模式 就是这样一种对象一种行为。

也许你会觉得B例子不如A例子,这个例子的确不能一眼就看出B例子比A例子优秀,

我当时也相当疑惑。B例子比A例子相同的功能不是还多了创建对象吗?画蛇添足?

System.out.println(MainDemo1.toDowncase(s)); // A例子
process(new Downcase(), s);          //B例子


思维扩展一下B例子的优点---一个对象一种行为:

优势1:维护性--但是假如的你要写的工具类很多比如几百种如将字符串倒转,将字符串去重复,将字符串去空格,将字符串转成字节........

于是A 例子这个类的代码就会越挤越多。而B例子创建对象就可以了,将来要维护很容易定位修改。
优势2:多人分工--如果是一个团队开发一个工具类,B例子的扩展性就比A例子强大的多。
优势3:编程的灵活性--《一个对象一种行为》,在动态的编程的非常灵活。配合委托非常棒。
(例如比如说植物大战僵尸,在某些场景普通僵尸走路方式变成蹦跳僵尸(外形不变),
我们定义每个僵尸都有script类,我们要改变僵尸的一个行为只要修改这个普通僵尸的script这个类脚本该为蹦跳僵尸)。
B例子就是利用多态为我们演示如何“使算法的责任和算法本身分割开来,委派给不同的对象管理"

由于这个例子没有体现算法的责任和算法本身分割的优点,为了更好理解这个模式:
我利用一些开源库http://www.jhlabs.com/ip/filters/index.html编写了滤镜项目demo。
其主要功能是图片---》滤镜---》滤镜图片效果 这个例子同时还用到模板模式



界面效果
MainTryImageUI.class //界面类

Action.class//动作

package com.jhlabs.work.ui;

import java.awt.image.BufferedImage;

import javax.swing.JMenuItem;

import com.jhlabs.image.AbstractBufferedImageOp;
import com.jhlabs.image.ContourFilter;
import com.jhlabs.image.DespeckleFilter;
import com.jhlabs.image.DiffusionFilter;
import com.jhlabs.image.EdgeFilter;
import com.jhlabs.image.EmbossFilter;
import com.jhlabs.image.EqualizeFilter;
import com.jhlabs.image.Flush3DFilter;
import com.jhlabs.image.LevelsFilter;
import com.jhlabs.image.LightFilter;
import com.jhlabs.image.MedianFilter;

import com.jhlabs.image.OilFilter;
import com.jhlabs.image.PlasmaFilter;
import com.jhlabs.image.QuantizeFilter;

import com.jhlabs.image.SmearFilter;

public enum Action {
//为每一个动作注册名称和对应的滤镜
ContourFilter("轮廓",new ContourFilter()),
DespeckleFilter("去斑",new DespeckleFilter()),
DiffusionFilter("扩散",new DiffusionFilter()),
EdgeFilter("滤光",new EdgeFilter()),
EmbossFilter("浮雕",new EmbossFilter()),
EqualizeFilter("补偿",new EqualizeFilter()),
Flush3DFilter("3D",new Flush3DFilter()),
LevelsFilter("水平",new LevelsFilter()),
LightFilter("光源",new LightFilter()),
MedianFilter("中线",new MedianFilter()),
OilFilter("曝光",new OilFilter()),
PlasmaFilter("等离子",new PlasmaFilter()),
QuantizeFilter("量子化",new QuantizeFilter()),
SmearFilter("风化",new SmearFilter());
//名称
private String name;
//按钮
private JMenuItem jMenuItem;
//滤镜
private AbstractBufferedImageOp filter;
//构造器
private Action(String name,AbstractBufferedImageOp filter) {
this.name = name;
this.jMenuItem=new JMenuItem(name);
this.filter=filter;
}
//指定动作进行滤镜操作
public static void actionScript(Action action,BufferedImage sourceBuf,BufferedImage targetBuf)
{
action.getFilter().filter(sourceBuf, targetBuf);
}
public AbstractBufferedImageOp getFilter() {
return filter;
}
public String getName() {
return name;
}
public JMenuItem getjMenuItem() {
return jMenuItem;
}

}


本文代码示例下载地址:http://download.csdn.net/detail/b275518834/4942096
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: