架构 之 使用子类多态 and 使用state模式(使用面向对象技术替代switch-case和if-else)
2014-05-15 14:34
633 查看
一篇不错的文章 原文地址:点击打开链接
在日常开发中,常常会作一些状态判断,用到swich-case与if-else。在面向对象的环境里,有两种方式可以替代它们。一种是使用继承子类的多态,另一种是使用state模式。它们使用对象的间接性有效地摆脱了传统的状态判断。
举个例子。
Method.java
[align=left]package com.zj.original;[/align] [align=left] [/align] [align=left]import com.zj.utils.NoMethodTypeException;[/align] [align=left] [/align] [align=left]public class Method {[/align] [align=left] private int _type;[/align] public static final int POST = 0; public static final int GET = 1; public static final int PUT = 2; public static final int DELETE = 3; [align=left] [/align] public Method(int type) { [align=left] _type = type;[/align] [align=left] }[/align] [align=left] [/align] public String getMethod() throws NoMethodTypeException { switch (_type) { [align=left] case POST:[/align] [align=left] return "This is POST method";[/align] [align=left] case GET:[/align] [align=left] return "This is GET method";[/align] [align=left] case PUT:[/align] [align=left] return "This is PUT method";[/align] [align=left] case DELETE:[/align] [align=left] return "This is DELETE method";[/align] [align=left] default:[/align] [align=left] throw new NoMethodTypeException();[/align] [align=left] }[/align] [align=left] }[/align] [align=left] [/align] public boolean safeMethod() { [align=left] if (_type == GET)[/align] [align=left] return true;[/align] [align=left] else[/align] [align=left] return false;[/align] [align=left] }[/align] [align=left] [/align] public boolean passwordRequired() { [align=left] if (_type == POST)[/align] [align=left] return false;[/align] [align=left] else[/align] [align=left] return true;[/align] [align=left] }[/align] [align=left]}[/align] |
1.使用继承子类多态
使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的(在对象的生存周期中)。
现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。
在抽象基类Method中可以提供创建子类实例的静态方法,当然也可以使用Simple Factory模式。对于getMethod()方法,延迟到子类中实现;对于safeMethod()方法和passwordRequired()方法,提供一个默认的实现,这个实现应该符合绝大部分子类的要求,这样的话,对于少数不符合默认实现的子类只需override相应方法即可。
<<abstract>>Method.java
[align=left]package com.zj.subclass;[/align] [align=left] [/align] public abstract class Method { [align=left] [/align] public final static Method createPostMethod() { [align=left] return new PostMethod();[/align] [align=left] }[/align] [align=left] [/align] public final static Method createGetMethod() { [align=left] return new GetMethod();[/align] [align=left] }[/align] [align=left] [/align] public final static Method createPutMethod() { [align=left] return new PutMethod();[/align] [align=left] }[/align] [align=left] [/align] public final static Method createDeleteMethod() { [align=left] return new DelMethod();[/align] [align=left] }[/align] [align=left] [/align] abstract public String getMethod(); [align=left] [/align] public boolean safeMethod() { [align=left] return false;[/align] [align=left] }[/align] [align=left] [/align] public boolean passwordRequired() { [align=left] return true;[/align] [align=left] }[/align] } |
PostMethod.java
[align=left]package com.zj.subclass;[/align] [align=left] [/align] public class PostMethod extends Method { [align=left] @Override[/align] [align=left] public String getMethod() {[/align] [align=left] return "This is POST method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] @Override[/align] public boolean passwordRequired() { [align=left] return false;[/align] [align=left] }[/align] } |
[align=left]package com.zj.subclass;[/align] [align=left] [/align] [align=left]public class GetMethod extends Method{[/align] [align=left] @Override[/align] [align=left] public String getMethod() {[/align] [align=left] return "This is GET method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] @Override[/align] public boolean safeMethod() { [align=left] return true;[/align] [align=left] }[/align] } |
[align=left]package com.zj.subclass;[/align] [align=left] [/align] public class PutMethod extends Method { [align=left] @Override[/align] [align=left] public String getMethod() {[/align] [align=left] return "This is PUT method";[/align] [align=left] }[/align] [align=left]}[/align] |
[align=left]package com.zj.subclass;[/align] [align=left] [/align] [align=left]public class DelMethod extends Method{[/align] [align=left] @Override[/align] [align=left] public String getMethod(){[/align] [align=left] return "This is DELETE method";[/align] [align=left] }[/align] } |
如果希望对象在生存周期内,可以变化自己的状态,则可以选择state模式。
这里抽象状态为一个接口MethodType,四种不同的状态实现该接口。
<<interface>>MethodType.java
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public interface MethodType {[/align] [align=left] String getTypeDescription();[/align] [align=left] [/align] [align=left] String getMethodDescription();[/align] [align=left] [/align] [align=left] boolean isSafe();[/align] [align=left] [/align] [align=left] boolean isRequired();[/align] } |
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public class Post implements MethodType{[/align] [align=left] public String getMethodDescription() {[/align] [align=left] return "This is POST method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] public String getTypeDescription() {[/align] [align=left] return "===POST===";[/align] [align=left] }[/align] [align=left] [/align] public boolean isRequired() { [align=left] return false;[/align] [align=left] }[/align] [align=left] [/align] public boolean isSafe() { [align=left] return false;[/align] [align=left] }[/align] } |
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public class Get implements MethodType{[/align] [align=left] public String getMethodDescription() {[/align] [align=left] return "This is GET method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] public String getTypeDescription() {[/align] [align=left] return "===GET===";[/align] [align=left] }[/align] [align=left] [/align] public boolean isRequired() { [align=left] return true;[/align] [align=left] }[/align] [align=left] [/align] public boolean isSafe() { [align=left] return true;[/align] [align=left] }[/align] [align=left]}[/align] |
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public class Put implements MethodType{[/align] [align=left] public String getMethodDescription() {[/align] [align=left] return "This is PUT method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] public String getTypeDescription() {[/align] [align=left] return "===PUT===";[/align] [align=left] }[/align] [align=left] [/align] public boolean isRequired() { [align=left] return true;[/align] [align=left] }[/align] [align=left] [/align] public boolean isSafe() { [align=left] return false;[/align] [align=left] }[/align] [align=left]}[/align] |
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public class Delete implements MethodType{[/align] [align=left] public String getMethodDescription() {[/align] [align=left] return "This is DELETE method";[/align] [align=left] }[/align] [align=left] [/align] [align=left] public String getTypeDescription() {[/align] [align=left] return "===DELETE===";[/align] [align=left] }[/align] [align=left] [/align] public boolean isRequired() { [align=left] return true;[/align] [align=left] }[/align] [align=left] [/align] public boolean isSafe() { [align=left] return false;[/align] [align=left] }[/align] } |
Method.java
[align=left]package com.zj.state;[/align] [align=left] [/align] [align=left]public class Method {[/align] [align=left] private MethodType _type;[/align] [align=left] [/align] [align=left] public Method() {[/align] [align=left] _type = null;[/align] [align=left] }[/align] [align=left] [/align] [align=left] public Method(MethodType type) {[/align] [align=left] _type = type;[/align] [align=left] }[/align] [align=left] [/align] [align=left] public String getMethod() {[/align] [align=left] return _type.getMethodDescription();[/align] [align=left] }[/align] [align=left] [/align] public boolean safeMethod() { [align=left] return _type.isSafe();[/align] [align=left] }[/align] [align=left] [/align] public boolean passwordRequired() { [align=left] return _type.isRequired();[/align] [align=left] }[/align] [align=left] [/align] public void changeType(MethodType type) { [align=left] _type = type;[/align] [align=left] }[/align] [align=left] [/align] public void runAllMethods() { [align=left] MethodType[] types = new MethodType[] { new Post(), new Get(),[/align] new Put(), new Delete() }; [align=left] for (MethodType type : types) {[/align] [align=left] System.out.println(type.getTypeDescription());[/align] [align=left] changeType(type);[/align] [align=left] System.out.println(getMethod());[/align] [align=left] System.out.println(safeMethod());[/align] [align=left] System.out.println(passwordRequired());[/align] [align=left] }[/align] [align=left] }[/align] } |
在测试类中,分别使用上面3中机制展示结果。它们的结果应该是一致的。
Client.java
[align=left]package com.zj.utils;[/align] [align=left] [/align] [align=left]public class Client {[/align] static void print(String s) { [align=left] System.out.println(s);[/align] [align=left] }[/align] [align=left] [/align] static void print(Boolean b) { [align=left] System.out.println(b);[/align] [align=left] }[/align] [align=left] [/align] public static void main(String[] args) throws NoMethodTypeException { [align=left] print("===original===");[/align] [align=left] print("===POST===");[/align] [align=left] com.zj.original.Method post1 = new com.zj.original.Method([/align] [align=left] com.zj.original.Method.POST);[/align] [align=left] print(post1.getMethod());[/align] [align=left] print(post1.safeMethod());[/align] [align=left] print(post1.passwordRequired());[/align] [align=left] print("===GET===");[/align] [align=left] com.zj.original.Method get1 = new com.zj.original.Method([/align] [align=left] com.zj.original.Method.GET);[/align] [align=left] print(get1.getMethod());[/align] [align=left] print(get1.safeMethod());[/align] [align=left] print(get1.passwordRequired());[/align] [align=left] print("===PUT===");[/align] [align=left] com.zj.original.Method put1 = new com.zj.original.Method([/align] [align=left] com.zj.original.Method.PUT);[/align] [align=left] print(put1.getMethod());[/align] [align=left] print(put1.safeMethod());[/align] [align=left] print(put1.passwordRequired());[/align] [align=left] print("===DELETE===");[/align] [align=left] com.zj.original.Method del1 = new com.zj.original.Method([/align] [align=left] com.zj.original.Method.DELETE);[/align] [align=left] print(del1.getMethod());[/align] [align=left] print(del1.safeMethod());[/align] [align=left] print(del1.passwordRequired());[/align] [align=left] [/align] [align=left] print("===subclass===");[/align] [align=left] print("===POST===");[/align] [align=left] com.zj.subclass.Method post2 = com.zj.subclass.Method[/align] [align=left] .createPostMethod();[/align] [align=left] print(post2.getMethod());[/align] [align=left] print(post2.safeMethod());[/align] [align=left] print(post2.passwordRequired());[/align] [align=left] print("===GET===");[/align] [align=left] com.zj.subclass.Method get2 = com.zj.subclass.Method.createGetMethod();[/align] [align=left] print(get2.getMethod());[/align] [align=left] print(get2.safeMethod());[/align] [align=left] print(get2.passwordRequired());[/align] [align=left] print("===PUT===");[/align] [align=left] com.zj.subclass.Method put2 = com.zj.subclass.Method.createPutMethod();[/align] [align=left] print(put2.getMethod());[/align] [align=left] print(put2.safeMethod());[/align] [align=left] print(put2.passwordRequired());[/align] [align=left] print("===DELETE===");[/align] [align=left] com.zj.subclass.Method del2 = com.zj.subclass.Method[/align] [align=left] .createDeleteMethod();[/align] [align=left] print(del2.getMethod());[/align] [align=left] print(del2.safeMethod());[/align] [align=left] print(del2.passwordRequired());[/align] [align=left] [/align] [align=left] print("===state===");[/align] [align=left] new com.zj.state.Method().runAllMethods();[/align] [align=left] }[/align] } |
相关文章推荐
- 使用面向对象技术替代switch-case和if-else
- 使用面向对象技术替代switch-case和if-else 推荐
- 使用面向对象技术替代switch-case和if-else
- 使用多态替代If else或switch的更多尝试
- 使用函数指针和多态代替冗长的if-else或者switch-case
- 使用函数指针和多态代替冗长的if-else或者switch-case
- 设计模式——行为型模式之借助策略模式(Strategy Pattern)减少使用不必要的if-else if -else和switch-case(三)
- 不使用乘除法,for,while,if,else,switch,case,条件判断语句(A?B:C) 实现:1+2+....+n
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 【九度1506】求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 【编程题目】求1+2+…+n, 要求不能使用乘除法、for、while、if、else、switch、case和条件语句
- PHP 不用求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- 使用状态模式(state pattern)替代if else
- C语言奇思妙想:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句(A?B:C)
- 一道面试题:求1+2+…+n,不使用乘除法、for、while、if 、else、switch、case 等关键字
- 题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。