关于去掉if判断的一些想法

本文探讨了一种在类中使用抽象方法和内部类来减少条件判断的编程技巧,并提出了使用反射作为另一种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个类中有两个私有变量
如X x1; X x2;

有一个方法 doSomthing(X x) {
    if ( x == x1 ) {
        ......
    } else if (x == x2){
       ........
    }
}

这样写当然可以,可是当X的实例越来越多的时候,if会写得越来越长,怎么才可以去除掉这个if判断呢?

一个想法,就是在X中加一个虚函数如叫doX.
X {
    abstract void doX();
}
那么
doSomething(X x) {
   x.doX(); 
}

这样是简洁了一些,实现方法可以有两个,第一就是用很多子类去实现这个X类,第二个是每个X new的时候都要去实现这个方法,这样写起来比较麻烦。
 
第一种实现方法
public abstract class X {

  abstract void doX();
}

public class X1 extends X {
  void doX(){....};
}

public class X2 extends X {
  void doX(){....};
}

public class Test {
  X x1 = new X1();
  X x2 = new X2();

  public void doSomething(X x) {
      x.doX();
  }
}

第二种实现方法
public abstract X {
  abstract void doX();
}

public class Test {
  X x1 = new X() {
     void doX(){
        ....
     }
  };

  X x2 = new X() {
     void doX(){
        ....
     }
  };

   public void doSomething(X x) {
       x.doX();
   }

}


第一种就是生成的子类会越来越多,感觉很难管理。而且不能读取Test类里面的变量。

第二种,Test类看起来结构有些复杂,但是可以读取Test里面的变量。

有没有更好一点的解决方法:(

 
 
可以用内部类实现
 
内部类实现,既可以访问里面的变量,又可以使整体结构好一点,但是整个类就有些复杂了一些:)
 
public abstract class X {

  abstract void doX();
}



public class Test {
  X x1 = new X1();
  X x2 = new X2();

  public void doSomething(X x) {
      x.doX();
  }
 
  private class X1 extends X {
    void doX(){....};
  }

  private class X2 extends X {
    void doX(){....};
  }
}
 
也可以用反射解决
 
在X里面增加一个属性String methodName,methodName对应的就是在Test类里面写的方法的名称,这样呢,最后靠反射就可以了,先得到方法名,然后呢就去调用方法。
 
public class X {
  private String methodName;
  public String getMethodName(){ return methodName};
  pyblic String setMethodName(String methodName){ this.methodName = methodName;}
 
  public X(){}
  public X(String methodName){this.methodName = methodName;}
}

public class Test {
   X x1 = new X("eat");
   X x2 = new X();
   x2.setMethodName("run");

   public void eat() {
     ..... 
   }

   public void run() {
     ..... 
   } 

   public void doSomething(X x) {
      String methodName = x.getMethodName();
      ...........
   }
}
后面的两种解决办法都可以,其实总体上我觉得还是第2种和第3种的解决办法好一些,当然了,第二种和第三种的取决要看是否去读取Test类中的属性了。
因为这两种解决办法都可以动态的增加X实例,而很少去改动其他无关的代码。
我简化了一下代码set RUNREGRESSION 1 # 全局日志函数 proc log_info {message log_file} { puts $log_file "[clock format [clock seconds]] - $message" } # 定义通用的测试用例执行过程,接受macro_name和log_file参数 proc run_test_case {macro_name log_file} { # 记录测试开始信息 log_info "Running test case: $macro_name" $log_file # 初始化测试结果为成功 set test_result "Passed" # 执行具体的测试逻辑 if {[catch { switch -exact -- $macro_name { "CYCLE_PERIOD_TESTCASE" { vsim -c -novopt work.tb_top -t ps -sva run 20ms log_info "$macro_name: Test completed successfully." $log_file } "UNBIAS_TESTCASE" { vsim -c -novopt work.tb_top -t ps -sva run 20ms log_info "$macro_name: Test completed successfully." $log_file } default { error "Unsupported test case: $macro_name" } } } result]} { # 测试失败,记录错误信息 log_info "Error running test case: $result" $log_file puts "Error running test case '$macro_name': $result" set test_result "Failed" } # 记录测试完成状态 if {$test_result == "Passed"} { log_info "$macro_name: Test completed successfully." $log_file } else { log_info "$macro_name: Test failed. Please check the logs." $log_file } } while {$RUNREGRESSION} { # 检查并打开文件列表 if {[catch {open "filelist.v" r} f]} { puts "Error opening filelist.v" exit 1 } # 遍历文件中的每一行 while {[gets $f line] != -1} { # 去除行首尾的空白字符 set line [string trim $line] if {$line eq ""} { continue } ;# 跳过空行 puts "Processing line: '$line'" # 检查是否为`define宏定义 if {[llength $line] >= 2 && [lindex $line 0] eq "`define"} { set macro_name [join [lrange $line 1 end]] # 打开测试用例的日志文件并运行测试 if {[catch {open "$macro_name.log" a} log_file]} { puts "Error opening log file for test case '$macro_name'" continue } # 记录开始信息 log_info "Test execution started for: $macro_name" $log_file # 尝试运行测试用例 run_test_case $macro_name $log_file # 记录结束信息 log_info "Test execution completed for: $macro_name" $log_file close $log_file ;# 关闭当前测试用例的日志文件 } else { puts "Invalid format in line: '$line'" } after 1000 ;# 延时1秒,避免频繁操作 } # 所有用例都运行完毕后退出循环 set RUNREGRESSION 0 close $f } puts "All test cases have been executed successfully. Please enjoy it!" 当第一个用例结束后打印了信息,但是跑第二个用例的时候,有执行了一次第一个用例。 ************************************************************************* # @ 0 Welcome to run CYCLE_PERIOD_TESTCASE testcase!!! # ************************************************************************* # # PPPPP A SSSS SSSS # PP P A A S S # PPPPP AAAAA SSS SSS # PP A A S S # PP A A SSSS SSSS # # ** Note: $stop : C:/Users/tommi wei/Desktop/vlast_p_sim/verilog_file/tb_top.sv(657) # Time: 7773787500 ps Iteration: 1 Instance: /tb_top # Break in Task CYCLE_PERIOD_TESTCASE at C:/Users/tommi wei/Desktop/vlast_p_sim/verilog_file/tb_top.sv line 657 # Processing line: '`define UNBIAS_TESTCASE' # End time: 16:07:27 on Jun 05,2025, Elapsed time: 0:00:14 ************************************************************************* # @ 0 Welcome to run CYCLE_PERIOD_TESTCASE testcase!!! # ************************************************************************* # # PPPPP A SSSS SSSS # PP P A A S S # PPPPP AAAAA SSS SSS # PP A A S S # PP A A SSSS SSSS # # ** Note: $stop : C:/Users/tommi wei/Desktop/vlast_p_sim/verilog_file/tb_top.sv(657) # Time: 7773787500 ps Iteration: 1 Instance: /tb_top
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值