策略模式和状态模式
策略模式和状态模式在类图上十分相似。都是高扩展性的设计。
两者最重要的区别是: 1. 策略模式封装的是不同的算法,算法之间没有交互,以达到算法可以自由切换的目的。2. 状态模式封装的是不同的状态,以达到状态切换行为随之发生改变的目的。
举一个场景。人在孩童时期玩耍,成年工作,老年退休。
按照策略模式是3种不同的工作方式,而按照状态模式,,则是认为人的状态不同产生了不同的行为结果,这里的行为相同,都是工作。
策略模式下的人生
public abstract class WorkAlgorithm{
public abstract void work();
}
public class ChildWork extends WorkAlgorithm{
@Override
public void work() {
System.out.println("child play for fun");
}
}
public class AudltWork extends WorkAlgorithm{
@Override
public void work() {
System.out.println("adult work for family");
}
}
public class OldWork extends WorkAlgorithm{
@Override
public void work() {
System.out.println("Older work for children's happiness");
}
}
public class Context{
private WorkAlgorithm worker;
public void setWork(WorkAlgorithm work){
this.worker=work;
}
public WorkAlgorithm getWork(){
return worker;
}
public void work(){
worker.work();
}
}
public class Client{
public static void main(String[] args){
Context context=new Context();
System.out.println("child work");
context.setWork(new ChildWork());
context.work();
System.out.println("Adult work");
context.setWork(new AdultWork());
context.work();
System.out.println("Older work");
context.setWork(new OldWork());
context.work();
}
}
状态模式的实现特点是:
状态本身持有上下文, 上下文又持有状态
public abstract class HumanState{
protected Human human;
public void setHuman(Human human){
this.human=human;
}
public abstract void work();
}
public class ChildState extends HumanState{
public void work{
System.out.println("child play for joy");
super.human.setState(Human.ADULT_STATE);
}
}
public class AdulteState extends HumanState{
public void work{
System.out.println("adult play for family");
super.human.setState(Human.OLD_STATE);
}
}
public class OldState extends HumanState{
public void work{
System.out.println("old play for enjoy");
}
}
public class Human{
public static final HumanState CHILD_STATE=new ChildState();
public static final HumanState ADULT_STATE=new AdulteState();
public static final HumanState OLD_STATE=new OldState();
private HumanState humanState;
public void setState(HumanState state){
this.humanState=state;
this.humanState.setHuman(this);
}
public void work(){
this.humanState.work();
}
}
public class Client{
public static void main(String[] args){
Human human=new Human();
human.setState(new ChildState());
System.out.println("child work");
human.work();
System.out.println("adult work");
human.work();
System.out.println("older work");
human.work();
}
}
策略模式和状态模式的不同
- 环境角色职责不同。 两者都有一个角色类称为Context(状态模式中就是Human) ,策略模式的环境角色就是一个委托作用,负责算法的替换,而状态模式不仅是委托行为,还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为随之切换的任务
- 解决问题的重点不同。 策略模式旨在解决内部算法如何改变对外界影响降低到最小,保证的是算法的切换。 状态模式解决的是内在状态的改变而引起行为改变的问题,它的出发点是事物的状态,封装状态而暴露行为,一个对象状态的改变,从外界看就是行为的改变
- 应用场景不同。 策略封装的是一系列平行的,可相互替换的算法。 而状态要求有状态有行为,不同状态不同行为,是一个二维的,行为和状态相关。
- 负责度不同。 策略模式比较简单,结构简单,扩展容易,代码容易阅读。 状态模式比较复杂, 上下文引用状态,状态又引用上下文。状态完成行为的同时,把上下文中的状态设置成下一个状态。