使用面向对象技术替代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. 使用继承子类多态
使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的 ( 在对象的生存周期中 )

现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。
在抽象基类 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();
    }
}
 

本文转自zhangjunhd51CTO博客,原文链接:http://blog.51cto.com/zhangjunhd/68070,如需转载请自行联系原作者
相关文章
|
存储 Cloud Native 编译器
openCV C++环境配置
openCV C++环境配置
|
缓存 JavaScript 前端开发
掌握现代JavaScript异步编程:Promises、Async/Await与性能优化
本文深入探讨了现代JavaScript异步编程的核心概念,包括Promises和Async/Await的使用方法、最佳实践及其在性能优化中的应用,通过实例讲解了如何高效地进行异步操作,提高代码质量和应用性能。
|
12月前
|
C语言
【C语言】全局搜索变量却找不到定义?原来是因为宏!
使用条件编译和 `extern` 来管理全局变量的定义和声明是一种有效的技术,但应谨慎使用。在可能的情况下,应该优先考虑使用局部变量、函数参数和返回值、静态变量或者更高级的封装技术(如结构体和类)来减少全局变量的使用。
209 5
|
弹性计算 Linux Shell
阿里云ecs linux系统如何进行系统盘的扩容
【1月更文挑战第25天】【1月更文挑战第122篇】阿里云ecs linux系统如何进行系统盘的扩容
801 1
|
机器学习/深度学习 人工智能 运维
构建高效自动化运维系统:DevOps与AI的融合
【5月更文挑战第19天】 在数字化转型的浪潮中,企业IT运维面临着日益复杂的挑战。传统的手动运维方式已经无法满足快速迭代和高可靠性的需求。本文探讨了如何通过结合DevOps理念和人工智能(AI)技术,构建一个高效的自动化运维系统。文章首先回顾了DevOps的核心原则及其在自动化运维中的应用,接着分析了AI如何增强故障预测、智能决策和自动化流程的能力。最后,提出了一个综合DevOps与AI技术的自动化运维框架,并讨论了其在实际部署中的优势和潜在挑战。
|
安全 Java 数据安全/隐私保护
快速掌握 WinRAR:详细安装与使用指南
**WinRAR 摘要** WinRAR 是全能压缩工具,支持多格式,如 RAR, ZIP 等。要下载,访问 &lt;https://www.win-rar.com&gt; 选择适合的操作系统和语言。安装时,定制路径和选项,如桌面快捷方式。启动后,通过“选项”-&gt;“设置”配置首选项。使用上,能新建压缩文件,设定格式和选项,也可解压文件到指定目录。遇到问题,如文件损坏,可利用 WinRAR 的修复功能。本文提供下载、安装和使用指导,确保用户顺利操作。
|
JavaScript 前端开发 测试技术
Vue.js开发的10大最佳实践
Vue.js开发的10大最佳实践
406 0
|
机器学习/深度学习 算法
基于GA优化的CNN-LSTM-Attention的时间序列回归预测matlab仿真
时间序列预测是许多领域中的核心问题,如金融市场分析、气候预测、交通流量预测等。近年来,深度学习在时间序列分析上取得了显著的成果,尤其是卷积神经网络(CNN)、长短时记忆网络(LSTM)和注意力机制(Attention)的结合使用
|
Ubuntu
./autogen.sh: 5: ./autogen.sh: autoreconf: not found
./autogen.sh: 5: ./autogen.sh: autoreconf: not found
533 1
|
机器学习/深度学习 传感器 算法
【粘菌算法】基于粘菌算法SMA求解单目标优化问题附matlab代码
【粘菌算法】基于粘菌算法SMA求解单目标优化问题附matlab代码