行为型模式

出处:http://blog.csdn.net/zhangerqing

行为型模式包括策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

  • 模式与模式之间的关系:

    第一类:通过父类与子类的关系进行实现。第二类:两个类之间。第三类:类的状态。第四类:通过中间类

一、策略模式

  策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户,需要设计一个接口为一系列实现类提供统一的方法,多个实现类试下该接口。设计一个抽象类做服装类,提供辅助函数

//统一接口:
public interface ICalculator {
public int calculate(String exp);
} //辅助类:
public abstract class AbstractCalculator { public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
} //三个实现类:
public class Plus extends AbstractCalculator implements ICalculator { @Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\+");
return arrayInt[0]+arrayInt[1];
}
}
public class Minus extends AbstractCalculator implements ICalculator { @Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"-");
return arrayInt[0]-arrayInt[1];
} }
public class Multiply extends AbstractCalculator implements ICalculator { @Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\*");
return arrayInt[0]*arrayInt[1];
}
} //简单的测试类:
public class StrategyTest { public static void main(String[] args) {
String exp = "2+8";
ICalculator cal = new Plus();
int result = cal.calculate(exp);
System.out.println(result); //10 }
}

  策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。

二、模板方法模式

  一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用

public abstract class AbstractCalculator {

    /*主方法,实现对本类其它方法的调用*/
public final int calculate(String exp,String opt){
int array[] = split(exp,opt);
return calculate(array[0],array[1]);
} /*被子类重写的方法*/
abstract public int calculate(int num1,int num2); public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
public class Plus extends AbstractCalculator { @Override
public int calculate(int num1,int num2) {
return num1 + num2;
}
} //测试类:
public class StrategyTest { public static void main(String[] args) {
String exp = "8+8";
AbstractCalculator cal = new Plus();
int result = cal.calculate(exp, "\\+");
System.out.println(result);
}
}

三、观察者模式

当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化,对象之间是一种一对多的关系

  MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象

public interface Observer {
public void update();
} //两个实现类:
public class Observer1 implements Observer { @Override
public void update() {
System.out.println("observer1 has received!");
}
}
public class Observer2 implements Observer { @Override
public void update() {
System.out.println("observer2 has received!");
} } //Subject接口及实现类:
public interface Subject { /*增加观察者*/
public void add(Observer observer); /*删除观察者*/
public void del(Observer observer); /*通知所有的观察者*/
public void notifyObservers(); /*自身的操作*/
public void operation();
} public abstract class AbstractSubject implements Subject { private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
} @Override
public void del(Observer observer) {
vector.remove(observer);
} @Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
} public class MySubject extends AbstractSubject { @Override
public void operation() {
System.out.println("update self!");
notifyObservers();
} } public class ObserverTest { public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
} }
//update self!
//observer1 has received!
//observer2 has received!

四、迭代子模式

  顺序访问聚集中的对象,一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问

//集合接口
public interface Collection { public Iterator iterator(); /*取得集合元素*/
public Object get(int i); /*取得集合大小*/
public int size();
}
//迭代器接口
public interface Iterator {
//前移
public Object previous(); //后移
public Object next();
public boolean hasNext(); //取得第一个元素
public Object first();
} //两个实现:
public class MyCollection implements Collection { public String string[] = {"A","B","C","D","E"};
@Override
public Iterator iterator() {
return new MyIterator(this);
} @Override
public Object get(int i) {
return string[i];
} @Override
public int size() {
return string.length;
}
} public class MyIterator implements Iterator { private Collection collection;
private int pos = -1; public MyIterator(Collection collection){
this.collection = collection;
} @Override
public Object previous() {
if(pos > 0){
pos--;
}
return collection.get(pos);
} @Override
public Object next() {
if(pos<collection.size()-1){
pos++;
}
return collection.get(pos);
} @Override
public boolean hasNext() {
if(pos<collection.size()-1){
return true;
}else{
return false;
}
} @Override
public Object first() {
pos = 0;
return collection.get(pos);
} } //测试类:
public class Test { public static void main(String[] args) {
Collection collection = new MyCollection();
Iterator it = collection.iterator(); while(it.hasNext()){
System.out.println(it.next());
}
}
} //A B C D E

五、责任链模式

  有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。

public interface Handler {
public void operator();
} public abstract class AbstractHandler { private Handler handler; public Handler getHandler() {
return handler;
} public void setHandler(Handler handler) {
this.handler = handler;
} } public class MyHandler extends AbstractHandler implements Handler { private String name; public MyHandler(String name) {
this.name = name;
} @Override
public void operator() {
System.out.println(name+"deal!");
if(getHandler()!=null){
getHandler().operator();
}
}
}
public class Test { public static void main(String[] args) {
MyHandler h1 = new MyHandler("h1");
MyHandler h2 = new MyHandler("h2");
MyHandler h3 = new MyHandler("h3"); h1.setHandler(h2);
h2.setHandler(h3); h1.operator();
}
} //h1deal!
//h2deal!
//h3deal!

六、命令模式

  只关注指令执行的结果,不关注底层如何实现执行

public interface Command {
public void exe();
}
public class MyCommand implements Command { private Receiver receiver; public MyCommand(Receiver receiver) {
this.receiver = receiver;
} @Override
public void exe() {
receiver.action();
}
}
public class Receiver {
public void action(){
System.out.println("command received!");
}
} public class Invoker { private Command command; public Invoker(Command command) {
this.command = command;
} public void action(){
command.exe();
}
}
public class Test { public static void main(String[] args) {
Receiver receiver = new Receiver();
Command cmd = new MyCommand(receiver);
Invoker invoker = new Invoker(cmd);
invoker.action(); //command received!
}
}

七、备忘录模式

  保存一个对象的某个状态,以便在适当的时候恢复对象,假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C是一个用来存储备忘录的,且只能存储,不能修改等操作。

  Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值。Memento类是备忘录类,Storage类是存储备忘录的类,持有Memento类的实例,该模式很好理解

public class Original {

    private String value;

    public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} public Original(String value) {
this.value = value;
} public Memento createMemento(){
return new Memento(value);
} public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
}
public class Memento { private String value; public Memento(String value) {
this.value = value;
} public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
}
}
public class Storage { private Memento memento; public Storage(Memento memento) {
this.memento = memento;
} public Memento getMemento() {
return memento;
} public void setMemento(Memento memento) {
this.memento = memento;
}
} //测试类:
public class Test { public static void main(String[] args) { // 创建原始类
Original origi = new Original("egg"); // 创建备忘录
Storage storage = new Storage(origi.createMemento()); // 修改原始类的状态
System.out.println("初始化状态为:" + origi.getValue());
origi.setValue("niu");
System.out.println("修改后的状态为:" + origi.getValue()); // 回复原始类的状态
origi.restoreMemento(storage.getMemento());
System.out.println("恢复后的状态为:" + origi.getValue());
}
}
//初始化状态为:egg
//修改后的状态为:niu
//恢复后的状态为:egg

八、状态模式

  可以通过改变状态来获得不同的行为,你的好友能同时看到你的变化

/**
* 状态类的核心类
*
*/
public class State { private String value; public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} public void method1(){
System.out.println("execute the first opt!");
} public void method2(){
System.out.println("execute the second opt!");
}
} /**
* 状态模式的切换类
*
*/
public class Context { private State state; public Context(State state) {
this.state = state;
} public State getState() {
return state;
} public void setState(State state) {
this.state = state;
} public void method() {
if (state.getValue().equals("state1")) {
state.method1();
} else if (state.getValue().equals("state2")) {
state.method2();
}
}
} //测试类: public class Test { public static void main(String[] args) { State state = new State();
Context context = new Context(state); //设置第一种状态
state.setValue("state1");
context.method(); //设置第二种状态
state.setValue("state2");
context.method();
}
}
//execute the first opt!
//execute the second opt!

九、访问模式

  访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果

public interface Visitor {
public void visit(Subject sub);
}
public class MyVisitor implements Visitor { @Override
public void visit(Subject sub) {
System.out.println("visit the subject:"+sub.getSubject());
}
}
//Subject类,accept方法,接受将要访问它的对象,getSubject()获取将要被访问的属性,
public interface Subject {
public void accept(Visitor visitor);
public String getSubject();
}
public class MySubject implements Subject { @Override
public void accept(Visitor visitor) {
visitor.visit(this);
} @Override
public String getSubject() {
return "love";
}
} //测试:
public class Test { public static void main(String[] args) { Visitor visitor = new MyVisitor();
Subject sub = new MySubject();
sub.accept(visitor);
}
}
//visit the subject:love

访问者模式增加新的数据结构很困难适用于数据结构相对稳定的系统,把数据结构和算法解耦

十、中介者模式

public interface Mediator {
public void createMediator();
public void workAll();
}
public class MyMediator implements Mediator { private User user1;
private User user2; public User getUser1() {
return user1;
} public User getUser2() {
return user2;
} @Override
public void createMediator() {
user1 = new User1(this);
user2 = new User2(this);
} @Override
public void workAll() {
user1.work();
user2.work();
}
}
public abstract class User { private Mediator mediator; public Mediator getMediator(){
return mediator;
} public User(Mediator mediator) {
this.mediator = mediator;
} public abstract void work();
}
public class User1 extends User { public User1(Mediator mediator){
super(mediator);
} @Override
public void work() {
System.out.println("user1 exe!");
}
}
public class User2 extends User { public User2(Mediator mediator){
super(mediator);
} @Override
public void work() {
System.out.println("user2 exe!");
}
} public class Test { public static void main(String[] args) {
Mediator mediator = new MyMediator();
mediator.createMediator();
mediator.workAll();
}
} //user1 exe!
//user2 exe!

十一、解释器模式

public interface Expression {
public int interpret(Context context);
} public class Plus implements Expression { @Override
public int interpret(Context context) {
return context.getNum1()+context.getNum2();
}
} public class Minus implements Expression { @Override
public int interpret(Context context) {
return context.getNum1()-context.getNum2();
}
} public class Context { private int num1;
private int num2; public Context(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
} public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
} } public class Test { public static void main(String[] args) { // 计算9+2-8的值
int result = new Minus().interpret((new Context(new Plus().interpret(new Context(9, 2)), 8)));
System.out.println(result);
}
} //3

最新文章

  1. CSS导航菜单水平居中的多种方法
  2. C#调用LUA函数
  3. gulp watch出现Error: watch null EPERM的问题解释
  4. spring 源码下载地址
  5. Tips12: 私人定制 专属的Unity3D 脚本模板
  6. ALV详解:Function ALV(二)
  7. linux下进程、端口号相互查看方法
  8. #pragma alloc_text 与 ALLOC_PRAGMA
  9. UNION、EXCEPT和INTERSECT操作查询结果
  10. WiEngine+Eclipse+CDT+Sequoyah实现c++编程智能感知提示
  11. Nginx简单操作
  12. 『Candies 差分约束系统』
  13. eclipse中导入java类失败的问题
  14. JavaScript1.6数组新特性和JQuery的几个工具方法
  15. Postman模拟Request Payload发送请求
  16. [BZOJ4820][SDOI2017]硬币游戏(高斯消元+KMP)
  17. 【Unity】UGUI的Text各种小问题
  18. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
  19. Linux(CentOS)下squid代理服务器配置-五岳之巅
  20. 我的Android进阶之旅------>Android自定义View来实现解析lrc歌词并同步滚动、上下拖动、缩放歌词的功能

热门文章

  1. 批量执行异步任务CompletionService
  2. THINKPHP_(5)_THINKPHP6接收ajax下拉菜单提交的数据,存在的bug
  3. 目标形体形状轮廓重建:ICCV2019论文解析
  4. 3DPytorch-API NVIDIA Kaolin
  5. 基于TensorRT的BERT实时自然语言理解(下)
  6. C++标准模板库(STL)——queue常见用法详解
  7. springboot实现自定义拦截器
  8. Visual Studio 2022 Preview 1 和.NET 6 Preview 5 正式发布
  9. mybatis-generator的使用心得
  10. Unity3D学习笔记1——绘制一个三角形