在日常开发中,常常会作一些状态判断,用到
swich-case
与
if-else
。在面向对象的环境里,有两种方式可以替代它们。一种是使用继承子类的多态,另一种是使用
state
模式。它们使用对象的间接性有效地摆脱了传统的状态判断。
举个例子。
Method.java
|
类 Method 中,存在四个状态 Post 、 Get 、 Put 和 Delete 。有一个 switch-case 判断,用于输出四种方法的描述信息;两个 if-else 判断,分别判断方法是否安全 ( 只有 Get 方法是安全的 ) ,方法是否需要密码 ( 只有 Post 方法不需要密码 ) 。
1. 使用继承子类多态
使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的 ( 在对象的生存周期中 ) 。
现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。
在抽象基类 Method 中可以提供创建子类实例的静态方法,当然也可以使用 Simple Factory 模式。对于 getMethod() 方法,延迟到子类中实现;对于 safeMethod() 方法和 passwordRequired() 方法,提供一个默认的实现,这个实现应该符合绝大部分子类的要求,这样的话,对于少数不符合默认实现的子类只需 override 相应方法即可。
<<abstract>>Method.java
|
四个子类分别继承和 override 相应的方法。
PostMethod.java
|
GetMethod.java
|
PutMethod.java
|
DelMethod.java
|
2. 使用 state 模式
如果希望对象在生存周期内,可以变化自己的状态,则可以选择 state 模式。
这里抽象状态为一个接口 MethodType ,四种不同的状态实现该接口。
<<interface>>MethodType.java
package com.zj.state;
public interface MethodType {
String getTypeDescription();
String getMethodDescription();
boolean isSafe();
boolean isRequired();
}
package com.zj.state;
publicinterface MethodType { String getTypeDescription();
String getMethodDescription();
boolean isSafe();
boolean isRequired(); } |
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 ;
}
}
package com.zj.state;
publicclass Post implements MethodType{ public String getMethodDescription() { return "This is POST method" ; }
public String getTypeDescription() { return "===POST===" ; }
publicboolean isRequired() { returnfalse ; }
publicboolean isSafe() { returnfalse ; } } |
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 ;
}
public Method(MethodType type) {
_type = type;
}
public String getMethod() {
return _type .getMethodDescription();
}
public boolean safeMethod() {
return _type .isSafe();
}
public boolean passwordRequired() {
return _type .isRequired();
}
public void changeType(MethodType type) {
_type = type;
}
public void runAllMethods() {
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 void print(Boolean b) {
System. out .println(b);
}
public static void main(String[] args) throws NoMethodTypeException {
print( "===original===" );
print( "===POST===" );
com.zj.original.Method post1 = new com.zj.original.Method(
com.zj.original.Method. POST );
print(post1.getMethod());
print(post1.safeMethod());
print(post1.passwordRequired());
print( "===GET===" );
com.zj.original.Method get1 = new com.zj.original.Method(
com.zj.original.Method. GET );
print(get1.getMethod());
print(get1.safeMethod());
print(get1.passwordRequired());
print( "===PUT===" );
com.zj.original.Method put1 = new com.zj.original.Method(
com.zj.original.Method. PUT );
print(put1.getMethod());
print(put1.safeMethod());
print(put1.passwordRequired());
print( "===DELETE===" );
com.zj.original.Method del1 = new com.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===" );
new com.zj.state.Method().runAllMethods();
}
}
转载于:https://blog.51cto.com/zhangjunhd/68070