java 枚举 状态机_JAVA枚举类状态机 与 Java枚举策略模式

写的比较晚了,贴代码供参考

1、普通的enum方法设计如下,缺点是不方便维护,因为是switch语句,容易在扩展的时候忘了改相关的代码。但如果你的代码千年不变,这个缺点就不明显。

注意:测试结果参见第2点。

package enumclass;

public enum PayrollBySwitch {

Monday,

Tuesday,

Wendsday,

Thursday,

Friday,

Saturday,

Sunday;

private static final int FIXED_WORK_HOUR_PER_DAY = 8;

//加班工资会是基本工资的一半。

private static final double OVER_TIME_PAY_RATE = 1/2;

public double pay(double workHours, double payPerHour){

double basePay = workHours * payPerHour;

double overTimePay = 0;

switch(this){

//周六日每个小时都算加班工资

case Saturday: case Sunday:

overTimePay = workHours * payPerHour * OVER_TIME_PAY_RATE;

break;

default:

overTimePay = workHours <= FIXED_WORK_HOUR_PER_DAY ?

0 : workHours - FIXED_WORK_HOUR_PER_DAY;

break;

}

return basePay+overTimePay;

}

}

2、enum方法的改进版,使用了enum strategy模式。要点:

1、设计一个private的enum,作为strategy的抽象。

2、顶层enum的构造器需要传入策略PayType。

3、策略类需要定义一个抽象类,让private enum去实现这个方法。这里用到enum的另一个特性:特定于常量的方法(Constant-specific class body的Constant -specific method implementation)。

package enumclass;

public enum PayrollByEnumStrategy {

Monday(PayType.WeekDay),

Tuesday(PayType.WeekDay),

Wendsday(PayType.WeekDay),

Thursday(PayType.WeekDay),

Friday(PayType.WeekDay),

Saturday(PayType.WeekEnd),

Sunday(PayType.WeekEnd);

PayType payType;

private PayrollByEnumStrategy(PayType payType) {

this.payType = payType;

}

public double pay(double workHours, double payPerHour){

return payType.pay(workHours, payPerHour);

}

private enum PayType{

WeekDay{

@Override

double overTimePay(double workHours, double payPerHour) {

double overTimePay = workHours <= FIXED_WORK_HOUR_PER_DAY ?

0 : (workHours - FIXED_WORK_HOUR_PER_DAY)*payPerHour*OVER_TIME_PAY_RATE;

return overTimePay;

}

},

WeekEnd{

@Override

double overTimePay(double workHours, double payPerHour) {

double overTimePay = workHours * payPerHour * OVER_TIME_PAY_RATE;

return overTimePay;

}

};

private static final int FIXED_WORK_HOUR_PER_DAY = 8;

//加班工资会是基本工资的一半。

private static final double OVER_TIME_PAY_RATE = 1/2;

abstract double overTimePay(double workHours, double payPerHour);

public double pay(double workHours, double payPerHour){

double basePay = workHours * payPerHour;

double overTimePay = overTimePay(workHours,payPerHour);

return basePay+overTimePay;

}

}

}

1 和 2的测试结果:

工资总额 by Switch= ¥3510.0

工资总额 by Enum Strategy= ¥3510.0

测试类如下:

package enumclass;

public class WorkPayment {

public static void main(String[] args) {

// TODO Auto-generated method stub

//计算一周的工资总额——每天工作10小时,每小时400块。

double sum = 0;

for(PayrollBySwitch day : PayrollBySwitch.values()){

sum += day.pay(10, 50);

}

System.out.println("工资总额 by Switch= ¥"+sum);

sum = 0;

for(PayrollBySwitch day : PayrollBySwitch.values()){

sum += day.pay(10, 50);

}

System.out.println("工资总额 by Enum Strategy= ¥"+sum);

}

}

3、覆盖enum的toString带来的方便。

如下面例子,打印日志时,很方便

package enumclass;

//enum strategy with toString overrided

public enum Operation {

PLUS("*") { double eval(double x, double y) { return x + y; } },

MINUS("-") { double eval(double x, double y) { return x - y; } },

TIMES("*") { double eval(double x, double y) { return x * y; } },

DIVIDE ("/"){ double eval(double x, double y) { return x / y; } };

String symbol = null;

Operation(String symbol){

this.symbol = symbol;

}

public String toString(){

return symbol;

}

// Do arithmetic op represented by this constant

abstract double eval(double x, double y);

}测试类

package enumclass;

public class OperationTest {

public static void main(String[] args) {

double x = 2.000;

double y = 4.0000;

for(Operation oper : Operation.values()){

System.out.printf("%f %s %f = %f%n",x,oper,y,oper.eval(x, y));

}

}

}

测试结果如下:

2.000000 * 4.000000 = 6.000000

2.000000 - 4.000000 = -2.000000

2.000000 * 4.000000 = 8.000000

2.000000 / 4.000000 = 0.500000

4、最后是状态机的实现,已上传。

要点:

1、enum可以实现interface。

2、状态机维护需要两种对象:Context上下文、States状态

3、Context管理State。

4、用while运行状态机,其实这个while放到Context内更好,应该是状态机自己维护状态,而不是外部通过状态机去控制状态。

5、比较巧的设计是,每个state的操作返回boolean,作为状态是否终止的判断。

资源:http://download.csdn.net/detail/xzongyuan/9871848

State设置为如下时:

context.state(States.WHITE);

运行结果:

Current State = WHITE

Current State = BLUE

package enumstatemachin;

public class InfiniteMachineTest {

public static void main(String[] args) {

Context context = new ContextImp();

context.state(States.WHITE);

while(context.state().process(context));

}

}

package enumstatemachin;

import java.nio.ByteBuffer;

enum States implements State {

RED {

public boolean process(Context context) {

context.state(States.GREEN);

System.out.println("Current State = " + this);

return true;

}

}, GREEN {

public boolean process(Context context) {

context.state(States.BLACK);

System.out.println("Current State = " + this);

return true;

}

},BLACK {

public boolean process(Context context) {

context.state(States.YELLOW);

System.out.println("Current State = " + this);

return true;

}

},YELLOW {

public boolean process(Context context) {

context.state(States.WHITE);

System.out.println("Current State = " + this);

return true;

}

},WHITE {

public boolean process(Context context) {

context.state(States.BLUE);

System.out.println("Current State = " + this);

return true;

}

},BLUE{

public boolean process(Context context) {

context.state(States.RED);

System.out.println("Current State = " + this);

return false;

}

};

public abstract boolean process(Context context);

}

package enumstatemachin;

interface State {

/**

* @return true to keep processing, false to read more data.

*/

boolean process(Context context);

}

package enumstatemachin;

import java.nio.ByteBuffer;

public interface Context {

State state();

void state(State state);

}

package enumstatemachin;

import java.nio.ByteBuffer;

public class ContextImp implements Context {

State state;

@Override

public State state() {

// TODO Auto-generated method stub

return state;

}

@Override

public void state(State state) {

this.state = state;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值