1.状态模式

State模式也叫状态模式,是行为设计模式的一种,State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样.

状态模式的应用场景

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转译到表现不同的状态的一系列类当中,可以吧复杂的判断逻辑简化.

状态模式的结构

java 状态模式策略 java的状态模式_java 状态模式策略

package com.ibeifeng.ex3;

public abstract class State {
	public abstract void  doSomething(Person person);
}
package com.ibeifeng.ex3;

public class MState extends State {

	public void doSomething(Person person) {
		if(person.getHour() == 7) {
			System.out.println("吃早餐");
		} else {
			person.setState(new LState());
			person.doSomething();
		}
	}

}
package com.ibeifeng.ex3;

public class LState extends State{

	public void doSomething(Person person) {
		if(person.getHour() == 12) {
			System.out.println("吃中饭");
		} else {
			person.setState(new SState());
			person.doSomething();
		}
	}

}
package com.ibeifeng.ex3;

public class SState extends State {

	public void doSomething(Person person) {
		if(person.getHour() == 18) {
			System.out.println("吃晚饭");
		} else {
			person.setState(new NoState());
			person.doSomething();
		}
	}

}
package com.ibeifeng.ex3;

public class NoState extends State {

	public void doSomething(Person person) {
		System.out.println(person.getHour() +  "未定义");
	}

}
package com.ibeifeng.ex3;

public class Person {
	private int hour;
	private State state;

	public int getHour() {
		return hour;
	}

	public void setHour(int hour) {
		this.hour = hour;
	}
	
	public Person() {
		state = new MState();
	}
	
	public void doSomething(){
//		if(hour == 7) {
//			state = new MState();
//			state.doSomething();
//		} else if(hour == 12) {
//			state = new LState();
//			state.doSomething();
//		} else if(hour == 18) {
//			state = new SState();
//			state.doSomething();
//		} else {
//			state = new NoState();
//			state.doSomething();
//		}
		state.doSomething(this);
		//复位,都所以方法以后再执行。
		state = new MState();
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}
}
package com.ibeifeng.ex3;

public class MainClass {
	public static void main(String[] args) {
		Person person = new Person();
		
		person.setHour(7);
		person.doSomething();
		
		person.setHour(12);
		person.doSomething();
		
		person.setHour(18);
		person.doSomething();
		
		person.setHour(8);
		person.doSomething();
		
		person.setHour(7);
		person.doSomething();
		
		person.setHour(18);
		person.doSomething();
		
	}
}

状态模式的角色和职责
Context:用户对象.拥有一个state类型的成员,以标识对象的当前状态;
State:接口或基类,封装与Context的特定状态相关的行为;
ConcreteState:接口实现类或子类,实现了一个与Context某个状态相关的行为.

2.命令模式

Command模式也叫做命令模式,是行为设计模式的一种.Commad模式用过被称为Command的类封装了对目标对象的调用行为以及调用参数.

命令模式的应用场景

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象的实例:设置调用参数:调用目标对象的方法.

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类,

/-整个调用过程比较繁杂,或者存在多处这种调用.这是,使用Command类对该调用加以封装,便于功能的再利用.

/-调用前后需要对调用参数进行某些处理.

/-调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等.

命令模式的结构

java 状态模式策略 java的状态模式_System_02

package com.ibeifemg.ex4;

public abstract class Command {
	private Peddler peddler;
	
	
	public Command(Peddler peddler) {
		this.peddler = peddler;
	}
	
	public Peddler getPeddler() {
		return peddler;
	}

	public void setPeddler(Peddler peddler) {
		this.peddler = peddler;
	}

	public abstract void sail();
}
package com.ibeifemg.ex4;

public class AppleCommand extends Command {

	public AppleCommand(Peddler peddler) {
		super(peddler);
	}

	public void sail() {
		this.getPeddler().sailApple();
	}
	
}
package com.ibeifemg.ex4;

public class BananaCommand extends Command{

	public BananaCommand(Peddler peddler) {
		super(peddler);
	}

	public void sail() {
		this.getPeddler().sailBanana();
	}

}
package com.ibeifemg.ex4;

/*
 * 小商贩
 */
public class Peddler {
	
	//卖苹果
	public void sailApple() {
		System.out.println("卖苹果");
	}
	
	//卖香蕉
	public void sailBanana() {
		System.out.println("卖香蕉");
	}
	
}
package com.ibeifemg.ex4;

import java.util.ArrayList;
import java.util.List;

public class Waiter {
	private List<Command> commands = new ArrayList<Command>();


	public void setOrder(Command command) {
		commands.add(command);
	}

	public void removeOrder(Command command) {
		commands.remove(command);
	}
	
	public void sail() {
		for(Command command : commands) {
			command.sail();
		}
	}
}
package com.ibeifemg.ex4;

public class MainClass {
	public static void main(String[] args) {
		Peddler peddler = new Peddler();
//		peddler.sailApple();
//		peddler.sailBanana();
		
		Command appleCommand = new AppleCommand(peddler);
		Command bananaCommand = new BananaCommand(peddler);
//		appleCommand.sail();
//		bananaCommand.sail();
		Waiter waiter = new Waiter();
		
		//下订单
		waiter.setOrder(appleCommand);
		waiter.setOrder(bananaCommand);
		
		//移除订单某项
		waiter.removeOrder(appleCommand);
		
		waiter.sail();
	}
}

命令模式的角色和职责
Command :command抽象类.
ConcreteCommand:Command的具体实现类.
Receiver:需要被调用的目标对象.
Invorker:通过Invorker执行Command对象.

3.访问者模式

Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作.

访问者模式的应用实例

比如有一个公园,有一到多个不同的组成部分:该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成.上级领导可以视察公园等等.也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性).

根据软件设计的开闭原则(对修改关闭,对扩展开放,)我们应该怎么实现这种需求呢?

java 状态模式策略 java的状态模式_状态模式_03

/*
 * 公园每一部分的抽象
 */
public interface ParkElement {
	//用来接纳访问者
	public void accept(Visitor visitor);
}
/*
 * 公园的A部分
 */
public class ParkA implements ParkElement {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

}
/*
 * 公园的B部分
 */
public class ParkB implements ParkElement{
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

}

public class Park implements ParkElement {
	private String name;
	private ParkA parkA;
	private ParkB parkB;
	
	public Park() {
		this.parkA = new ParkA();
		this.parkB = new ParkB();
		parkA.setName("A");
		parkB.setName("B");
	}

	public void accept(Visitor visitor) {
		visitor.visit(this);
		parkA.accept(visitor);
		parkB.accept(visitor);
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
/*
 * 访问者
 */
public interface Visitor {
	public void visit(Park park);
	public void visit(ParkA parkA);
	public void visit(ParkB parkB);
}
/*
 * 清洁工A,负责parkA的卫生情况
 */
public class VisitorA implements Visitor {

	public void visit(Park park) {

	}

	public void visit(ParkA parkA) {
		System.out.println("清洁工A:完成公园" + parkA.getName()+ "的卫生");
	}

	public void visit(ParkB parkB) {

	}

}
/*
 * 清洁工B,负责公园B部分的卫生
 */
public class VisitorB implements Visitor {

	public void visit(Park park) {

	}

	public void visit(ParkA parkA) {

	}

	public void visit(ParkB parkB) {
		System.out.println("清洁工B:完成公园" + parkB.getName()+"的卫生");
	}

}

public class VisitorManager implements Visitor {

	public void visit(Park park) {
		System.out.println("管理员:负责" + park.getName() + "卫生检查");
	}

	public void visit(ParkA parkA) {
		System.out.println("管理员:负责公园"+ parkA.getName() +"部分卫生检查");
	}

	public void visit(ParkB parkB) {
		System.out.println("管理员:负责公园"+ parkB.getName() +"分部卫生检查");
	}

}

public class MainClass {
	public static void main(String[] args) {
		Park park = new Park();
		park.setName("越秀公园");
		VisitorA visitorA = new VisitorA();
		
		park.accept(visitorA);
		
		VisitorB visitorB = new VisitorB();
		park.accept(visitorB);
		
		VisitorManager visitorManager = new VisitorManager();
		park.accept(visitorManager);
	}
}

访问者模式的角色和职责:
1)访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。
3) 元素角色(Element):定义一个Accept操作,它以一个访问者为参数。
4) 具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作。
5) 对象结构角色(Object Structure): 这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。