使用面向对象技术替代switch-case和if-else

本文出自 “子 孑 ” 博客,http://zhangjunhd.blog.51cto.com/113473/68070

  在日常开发中,常常会作一些状态判断,用到 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 new NoMethodTypeException();
       }
    }
 
    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. 使用继承子类多态
使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的 ( 在对象的生存周期中 )

现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。
在抽象基类 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 new GetMethod();
    }
 
    public final static Method createPutMethod() {
       return new PutMethod();
    }
 
    public final static Method createDeleteMethod() {
       return new DelMethod();
    }
 
    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" ;
    }
}
2. 使用 state 模式
如果希望对象在生存周期内,可以变化自己的状态,则可以选择 state 模式。

这里抽象状态为一个接口 MethodType ,四种不同的状态实现该接口。
<<interface>>MethodType.java
package com.zj.state;
 
public interface 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 ;
    }
}
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();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值