在日常开发中,常常会作一些状态判断,用到 swich-case 与 if-else 。在面向对象的环境里,有两种方式可以替代它们。一种是使用继承子类的多态,另一种是使用 state 模式。它们使用对象的间接性有效地摆脱了传统的状态判断。 举个例子。 Method.java
package com.zj.original; import com.zj.utils.NoMethodTypeException; public class Method { private int _type ; public static final int POST = 0; public static final int GET = 1; public static final int PUT = 2; public static final int DELETE = 3; public Method( int type) { _type = type; } public String getMethod() throws NoMethodTypeException { switch ( _type ) { case POST : return "This is POST method" ; case GET : return "This is GET method" ; case PUT : return "This is PUT method" ; case DELETE : return "This is DELETE method" ; default : throw newNoMethodTypeException(); } } public boolean safeMethod() { if ( _type == GET ) return true ; else return false; } public boolean passwordRequired() { if ( _type == POST ) return false ; else return true; } } |
类 Method 中,存在四个状态 Post 、 Get 、 Put 和 Delete 。有一个 switch-case 判断,用于输出四种方法的描述信息;两个 if-else 判断,分别判断方法是否安全 ( 只有 Get 方法是安全的 ) ,方法是否需要密码 ( 只有 Post 方法不需要密码 ) 。
1. 使用继承子类多态使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的 ( 在对象的生存周期中 ) 。
![](/image/../p_w_upload/200803/200803251206456773541.jpg)
现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。 在抽象基类 Method 中可以提供创建子类实例的静态方法,当然也可以使用 Simple Factory 模式。对于 getMethod() 方法,延迟到子类中实现;对于 safeMethod() 方法和 passwordRequired() 方法,提供一个默认的实现,这个实现应该符合绝大部分子类的要求,这样的话,对于少数不符合默认实现的子类只需 override 相应方法即可。 <<abstract>>Method.java
package com.zj.subclass; public abstract class Method { public final static Method createPostMethod() { return new PostMethod(); } public final static Method createGetMethod() { return newGetMethod(); } public final static Method createPutMethod() { return newPutMethod(); } public final static Method createDeleteMethod() { return newDelMethod(); } abstract public String getMethod(); public boolean safeMethod() { return false; } public boolean passwordRequired() { return true; } } |
四个子类分别继承和 override 相应的方法。 PostMethod.java
package com.zj.subclass; public class PostMethod extends Method { @Override public String getMethod() { return"This is POST method" ; } @Override public boolean passwordRequired() { return false; } } |
GetMethod.java
package com.zj.subclass; public class GetMethod extends Method{ @Override public String getMethod() { return"This is GET method" ; } @Override public boolean safeMethod() { return true; } } |
PutMethod.java
package com.zj.subclass; public class PutMethod extends Method { @Override public String getMethod() { return"This is PUT method" ; } } |
DelMethod.java
package com.zj.subclass; public class DelMethod extends Method{ @Override public String getMethod(){ return"This is DELETE method" ; } } |
如果希望对象在生存周期内,可以变化自己的状态,则可以选择 state 模式。
这里抽象状态为一个接口 MethodType ,四种不同的状态实现该接口。 <<interface>>MethodType.java
package com.zj.state; public interface MethodType { String getTypeDescription(); String getMethodDescription(); boolean isSafe(); booleanisRequired(); } |
Post.java
package com.zj.state; public class Post implements MethodType{ public String getMethodDescription() { return "This is POST method" ; } public String getTypeDescription() { return"===POST===" ; } public boolean isRequired() { return false; } public boolean isSafe() { return false; } } |
Get.java
package com.zj.state; public class Get implements MethodType{ public String getMethodDescription() { return "This is GET method" ; } public String getTypeDescription() { return"===GET===" ; } public boolean isRequired() { return true; } public boolean isSafe() { return true; } } |
Put.java
package com.zj.state; public class Put implements MethodType{ public String getMethodDescription() { return "This is PUT method" ; } public String getTypeDescription() { return"===PUT===" ; } public boolean isRequired() { return true; } public boolean isSafe() { return false; } } |
Delete.java
package com.zj.state; public class Delete implements MethodType{ public String getMethodDescription() { return "This is DELETE method" ; } public String getTypeDescription() { return"===DELETE===" ; } public boolean isRequired() { return true; } public boolean isSafe() { return false; } } |
此时,在类 Method 中保存一个 field 表示 MethodType ,在某对象中,可以随时变化四种已知的状态 ( 具体见 runAllMethods() 方法 ) 。 Method.java
package com.zj.state; public class Method { private MethodType _type ; public Method() { _type = null; } publicMethod(MethodType type) { _type = type; } public String getMethod() { return_type .getMethodDescription(); } public boolean safeMethod() { return_type .isSafe(); } public boolean passwordRequired() { return_type .isRequired(); } public voidchangeType(MethodType type) { _type = type; } public voidrunAllMethods() { MethodType[] types = new MethodType[] { new Post(), new Get(), new Put(), new Delete() }; for(MethodType type : types) { System. out .println(type.getTypeDescription()); changeType(type); System. out .println(getMethod()); System. out .println(safeMethod()); System. out .println(passwordRequired()); } } } |
3.测试
在测试类中,分别使用上面 3 中机制展示结果。它们的结果应该是一致的。 Client.java
package com.zj.utils; public class Client { static void print(String s) { System. out .println(s); } static voidprint(Boolean b) { System. out .println(b); } public static void main(String[] args) throwsNoMethodTypeException { print( "===original===" ); print( "===POST===" ); com.zj.original.Method post1 = newcom.zj.original.Method( com.zj.original.Method. POST ); print(post1.getMethod()); print(post1.safeMethod()); print(post1.passwordRequired()); print( "===GET===" ); com.zj.original.Method get1 = newcom.zj.original.Method( com.zj.original.Method. GET ); print(get1.getMethod()); print(get1.safeMethod()); print(get1.passwordRequired()); print( "===PUT===" ); com.zj.original.Method put1 = newcom.zj.original.Method( com.zj.original.Method. PUT ); print(put1.getMethod()); print(put1.safeMethod()); print(put1.passwordRequired()); print( "===DELETE===" ); com.zj.original.Method del1 = newcom.zj.original.Method( com.zj.original.Method. DELETE ); print(del1.getMethod()); print(del1.safeMethod()); print(del1.passwordRequired()); print( "===subclass===" ); print( "===POST===" ); com.zj.subclass.Method post2 = com.zj.subclass.Method .createPostMethod(); print(post2.getMethod()); print(post2.safeMethod()); print(post2.passwordRequired()); print( "===GET===" ); com.zj.subclass.Method get2 = com.zj.subclass.Method.createGetMethod(); print(get2.getMethod()); print(get2.safeMethod()); print(get2.passwordRequired()); print( "===PUT===" ); com.zj.subclass.Method put2 = com.zj.subclass.Method.createPutMethod(); print(put2.getMethod()); print(put2.safeMethod()); print(put2.passwordRequired()); print( "===DELETE===" ); com.zj.subclass.Method del2 = com.zj.subclass.Method .createDeleteMethod(); print(del2.getMethod()); print(del2.safeMethod()); print(del2.passwordRequired()); print( "===state===" ); newcom.zj.state.Method().runAllMethods(); } } |
转载于:https://blog.51cto.com/zhangjunhd/68070