【Java设计模式】状态模式处理返回码

来源:互联网 发布:查询的sql语句 编辑:程序博客网 时间:2024/05/29 09:40

一、状态模式:

首先来谈谈状态模式的定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

定义往往是那么的枯燥难懂,换一个表述方式可能更容易理解:状态模式把对象的行为包装在不同的状态对象里,每一个状态对象都有一个共同的抽象状态基类。这个表述结合状态模式的UML类图就挺好理解了,状态类StateA、SateB继承(实现)基类(接口)State,Context是State的管理类,它存有一个State的实例,即当前状态,当客户端调用其doSomething方法时,Context将调用State的doSomething方法,做对应状态的处理。

那么,状态模式可以用来处理什么问题呢?在本例中,主要解决以下问题:

1.避免多重if else的硬编码判断;

2.职责隔离,把返回码用类封装起来处理;

3.开放闭合,避免新增返回码后,需改动逻辑相关类。

二、返回码处理:

我们在开发客户端,请求服务器时,服务器会响应请求,并返回信息,这些信息中,往往包含一个字段:返回码。不同返回码,表述着本次请求不同的状态,所以我们客户端需要作出响应的处理。上代码:

Server server = new Server();Map m = server.request();if(m.get("return_code").toString().equals("0000")){//doSomething}else if(m.get("return_code").toString().equals("0001")){//doSomething}else if(m.get("return_code").toString().equals("0140")){//doSomething}

这样写的话,当我们返回码种类增多时,就要不断地增加else if,导致这个类的职责过大,代码过于臃肿。

这个时候,我们就需要状态模式了。首先,上UML类图。

首先,我们创建基类ReturnCode。

public interface ReturnCode{void doOnReturn(Map m);}
其次,创建其子类。

public class ReturnCode0000 implements ReturnCode{@Overridepublic void doOnReturn(Map m) {System.out.println("return code = 0000");}}
public class ReturnCode0001 implements ReturnCode{        @Override        public void doOnReturn(Map m) {                System.out.println("return code = 0001");        }}
public class ReturnCode0140 implements ReturnCode{         @Override         public void doOnReturn(Map m) {                 System.out.println("return code = 0140");         }}
再者,创建上下文类:

public class RCContext {private ReturnCode rc;public void handleReturn(Map m){String return_code = String.valueOf(m.get("return_code"));                if(return_code.equals("0000")){rc = new ReturnCode0000(); rc.doOnReturn(m);}else if(return_code.equals("0001")){rc = new ReturnCode0001(); rc.doOnReturn(m);}else if(return_code.equals("0140")){rc = new ReturnCode0140(); rc.doOnReturn(m);} }}

客户端代码:
public class Client {public static void main(String[] args) {Server server = new Server();Map m = server.request();RCContext net = new RCContext();net.handleReturn(m);}}
这样,我们就将逻辑判断交给上下文类RCContext了。但是这样的话,依然避免不了if else,每次我们新增一类返回码时,我们还需要对RCContext进行修改,违背开闭原则。这时候,则需要利用反射,通过规范命名,从类名实例化出所需要的类,优化后RCContext代码如下:
public class RCContext {private ReturnCode rc;public void handleReturn(Map m){String return_code = String.valueOf(m.get("return_code"));if(!return_code.equals("0000")){try {//Class clazz = Class.forName(this.getClass().getPackage().getName() + ".ReturnCode" + return_code);rc = (ReturnCode) clazz.newInstance();rc.doOnReturn(m);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}else{//返回码为0000,说明返回成功,此返回码比较频繁,因此我们直接实例化,以避免反射所带来的性能消耗rc = new ReturnCode0000();rc.doOnReturn(m);}}}
这样,我们不仅干掉了一堆if else,并且我们如果新增返回码规则之后,只需要在指定包内新建一个ReturnCodeXXXX的类即可。
0 0