赞
踩
注:示例来自《大话设计模式》
假如现有如下场景 员工上班 根据一天的时间变化 员工的状态也随之改变 如上午状态好 中午想睡觉 下午渐恢复 加班苦煎熬 初步代码实现如下
package Test16;
public class Program {
static int Hour = 0;
static boolean WorkFinished = false;
public static void main(String[] args)
{
Hour = 9;
WriteProgram();
Hour = 10;
WriteProgram();
Hour = 12;
WriteProgram();
Hour = 13;
WriteProgram();
Hour = 14;
WriteProgram();
Hour = 17;
WorkFinished = true;
//WorkFinished = false;
WriteProgram();
Hour = 19;
WriteProgram();
Hour = 22;
WriteProgram();
}
public static void WriteProgram()
{
if (Hour < 12)
{
System.out.println("当前时间:"+Hour+"点 上午工作,精神百倍");
}
else if (Hour < 13)
{
System.out.println("当前时间:"+Hour+"点 饿了,午饭;犯困,午休。");
}
else if (Hour < 17)
{
System.out.println("当前时间:"+Hour+"点 下午状态还不错,继续努力");
}
else
{
if (WorkFinished)
{
System.out.println("当前时间:"+Hour+"点 下班回家了");
}
else
{
if (Hour < 21)
{
System.out.println("当前时间:"+Hour+"点 加班哦,疲累之极");
}
else
{
System.out.println("当前时间:"+Hour+"点 不行了,睡着了。");
}
}
}
}
}
上面的写法是面向过程的代码 下面我们用面向对象的方式重构 代码如下
工作类
package Test16;
//工作
public class Work {
//钟点
private int hour;
//任务完成
private boolean finish = false;
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
public void WriteProgram()
{
if (hour < 12)
{
System.out.println("当前时间:"+hour+"点 上午工作,精神百倍");
}
else if (hour < 13)
{
System.out.println("当前时间:"+hour+"点 饿了,午饭;犯困,午休。");
}
else if (hour < 17)
{
System.out.println("当前时间:"+hour+"点 下午状态还不错,继续努力");
}
else
{
if (finish)
{
System.out.println("当前时间:"+hour+"点 下班回家了");
}
else
{
if (hour < 21)
{
System.out.println("当前时间:"+hour+"点 加班哦,疲累之极");
}
else
{
System.out.println("当前时间:"+hour+"点 不行了,睡着了。");
}
}
}
}
}
客户端代码
package Test16;
public class Program {
public static void main(String[] args)
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.setHour(9);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(10);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(12);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(13);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(14);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(17);
//emergencyProjects.WorkFinished = true;
emergencyProjects.setFinish(false);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(19);
emergencyProjects.WriteProgram();
emergencyProjects.setHour(22);
emergencyProjects.WriteProgram();
}
}
上面的写法 WriteProgram方法里分支过多 违背了开放-封闭原则和单一职责原则 面向对象设计其实就是希望做到代码的责任分解 下面我们用状态模式进行重构 代码如下
抽象状态类
package Test16;
//抽象状态
public abstract class State {
public abstract void WriteProgram(Work w);
}
上午和中午工作状态类
package Test16;
//上午工作状态
public class ForenoonState extends State {
@Override
public void WriteProgram(Work w)
{
if (w.getHour() < 12)
{
System.out.println("当前时间:"+w.getHour()+"点 上午工作,精神百倍");
}
else
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
}
package Test16;
//中午工作状态
public class NoonState extends State {
@Override
public void WriteProgram(Work w) {
if (w.getHour() < 13)
{
System.out.println("当前时间:"+w.getHour()+"点 饿了,午饭;犯困,午休。");
}
else
{
w.SetState(new AfternoonState());
w.WriteProgram();
}
}
}
下午和傍晚工作状态类
package Test16;
//下午工作状态
public class AfternoonState extends State {
@Override
public void WriteProgram(Work w) {
if (w.getHour() < 17)
{
System.out.println("当前时间:"+w.getHour()+"点 下午状态还不错,继续努力");
}
else
{
w.SetState(new EveningState());
w.WriteProgram();
}
}
}
package Test16;
//晚间工作状态
public class EveningState extends State {
@Override
public void WriteProgram(Work w) {
if (w.isFinish())
{
w.SetState(new RestState());
w.WriteProgram();
}
else
{
if (w.getHour() < 21)
{
System.out.println("当前时间:"+w.getHour()+"点 加班哦,疲累之极");
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
}
睡眠状态和下班休息状态类
package Test16;
//睡眠状态
public class SleepingState extends State {
@Override
public void WriteProgram(Work w) {
System.out.println("当前时间:"+w.getHour()+"点 不行了,睡着了。");
}
}
package Test16;
//下班休息状态
public class RestState extends State {
@Override
public void WriteProgram(Work w) {
System.out.println("当前时间:"+w.getHour()+"点 下班回家了");
}
}
工作类
package Test16;
//工作
public class Work {
//钟点
private int hour;
//任务完成
private boolean finish = false;
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public boolean isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
private State current;
public Work()
{
current = new ForenoonState();
}
public void SetState(State s)
{
current = s;
}
public void WriteProgram()
{
current.WriteProgram(this);
}
}
客户端代码不变
状态模式 当一个对象的内在状态改变时允许改变其行为 这个对象看起来像是改变了其类
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况 把状态的判断逻辑转移到表示不同状态的一系列类当中 可以把复杂的判断逻辑简化
状态模式的好处是将与特定状态相关的行为局部化 并且将不同状态的行为分割开来 就是将特定的状态相关的行为都放入一个对象中 由于所有与状态相关的代码都存在于某个子类中 所以通过定义新的子类可以很容易地增加新的状态和转换 说白了 就是为了消除庞大的条件分支语句 状态模式通过把各种状态转移逻辑分布到抽象类的子类之间 来减少相互间的依赖
当一个对象的行为取决于它的状态 并且它必须在运行时刻根据状态改变它的行为时 就可以考虑使用状态模式了
缺点 会产生较多的子类
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。