状态模式 State Pattern
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
在生产流水线上,每个岗位的工人完成自己的步骤后,产品状态发生变化,工人会交给下一环节处理。
如果用代码来描述一条披萨生产流水线,可以用状态模式。Pizza类为Context角色,它封装了客户端感兴趣的处理和查看状态接口,并将与状态相关的操作委托给当前状态对象(Cook)来处理。
UML图:
代码:
public class Pizza {
private String process;
private Cook cook;
public Pizza() {
this.process = "";
this.cook = new CrustCook();
}
public void setCook(Cook cook) {
this.cook = cook;
}
public void cooking() {
this.cook.cooking(this);
}
public String getProcess() {
return process;
}
public void setProcess(String process) {
this.process = process;
}
}
public abstract class Cook {
public abstract void cooking(Pizza pizza);
}
public class CrustCook extends Cook {
@Override
public void cooking(Pizza pizza) {
if (pizza.getProcess().equals("")) {
pizza.setProcess("crust");
System.out.println("制作面饼");
} else {
pizza.setCook(new IngredientsCook());
pizza.cooking();
}
}
}
public class IngredientsCook extends Cook {
@Override
public void cooking(Pizza pizza) {
if("crust".equals(pizza.getProcess())) {
pizza.setProcess("crust,ingredients");
System.out.println("加入馅料");
} else {
pizza.setCook(new SauceCook());
pizza.cooking();
}
}
}
public class SauceCook extends Cook {
@Override
public void cooking(Pizza pizza) {
if("crust,ingredients".equals(pizza.getProcess())) {
pizza.setProcess("crust,ingredients,sauce");
System.out.println("加入酱料");
} else {
pizza.setCook(new CheeseCook());
pizza.cooking();
}
}
}
public class CheeseCook extends Cook {
@Override
public void cooking(Pizza pizza) {
if("crust,ingredients,sauce".equals(pizza.getProcess())) {
pizza.setProcess("crust,ingredients,sauce,cheese");
System.out.println("加入芝士");
} else {
pizza.setCook(new BakeCook());
pizza.cooking();
}
}
}
public class BakeCook extends Cook {
@Override
public void cooking(Pizza pizza) {
if("crust,ingredients,sauce,cheese".equals(pizza.getProcess())) {
System.out.println("制作完成");
} else {
System.out.println("制作失败");
}
}
}
客户端:
public class Client {
public static void main(String[] args) {
Pizza pizza = new Pizza();
pizza.cooking();
pizza.cooking();
pizza.cooking();
pizza.cooking();
pizza.cooking();
}
}