天天看點

使用面向對象技術替代switch-case和if-else

在日常開發中,常常會作一些狀态判斷,用到 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. 使用繼承子類多态

使用繼承子類多态的方式,通常對于某個具體對象,它的狀态是不可改變的 ( 在對象的生存周期中 ) 。

使用面向對象技術替代switch-case和if-else

現在使用四個子類分别代表四種類型的方法。這樣就可以使用多态将各個方法的具體邏輯分置到子類中去了。 在抽象基類 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 模式。

使用面向對象技術替代switch-case和if-else

這裡抽象狀态為一個接口 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();

    }

}

轉載于:https://blog.51cto.com/zhangjunhd/68070