多if判断如何简化

代码如下

for(循环 itemId){

    if (itemId.equals(EnumBodyData.PBF.name())) {
        recordBodyData.setPbf(bodyDataValue.getValue());
        recordBodyData.setPbfIdeal(bodyDataValue.getIdealValue());
        recordBodyData.setPbfTip(bodyDataValue.getTip());
    }
    if (itemId.equals(EnumBodyData.BMI.name())) {
        recordBodyData.setBmi(bodyDataValue.getValue());
        recordBodyData.setBmiIdeal(bodyDataValue.getIdealValue());
        recordBodyData.setBmiTip(bodyDataValue.getTip());
    }
    if (itemId.equals(EnumBodyData.WT.name())) {
        recordBodyData.setWt(bodyDataValue.getValue());
        recordBodyData.setWtIdeal(bodyDataValue.getIdealValue());
        recordBodyData.setWtTip(bodyDataValue.getTip());
    }
    if (itemId.equals(EnumBodyData.WHR.name())) {
        recordBodyData.setWhr(bodyDataValue.getValue());
        recordBodyData.setWhrIdeal(bodyDataValue.getIdealValue());
        recordBodyData.setWhrTip(bodyDataValue.getTip());
    }
    if (itemId.equals(EnumBodyData.BFM.name())) {
        recordBodyData.setBfm(bodyDataValue.getValue());
        recordBodyData.setBfmIdeal(bodyDataValue.getIdealValue());
        recordBodyData.setBfmTip(bodyDataValue.getTip());
    }
}
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
最佳答案
if内的差别只有后面字符串:
recordBodyData.setPbf(bodyDataValue.getValue()):  "pdf" 
recordBodyData.setBmi(bodyDataValue.getValue()) : "Bmi"
recordBodyData.setWt(bodyDataValue.getValue()): "Wt"

那么将字符串作为方法调用即可。



$maps = [
    EnumBodyData.PBF.name() => 'pdf',
    EnumBodyData.BMI.name() => 'Bmi',
    EnumBodyData.WT.name() => 'Wt'
]

for(循环 itemId){
    foreach($maps as $condition_str => $method_str){
        if( itemId.equals($condition_str ) ){
            recordBodyData.{'set' + $method_str}(bodyDataValue.getValue())
            recordBodyData.{'set' + $method_str + 'Ideal'}(bodyDataValue.getValue())
            recordBodyData.{'set' + $method_str + 'Tip'}(bodyDataValue.getValue())
        }
    }
}
ps: 有点忘记php语法 这方案铁定可行的
6个月前 评论
博学多才的走停 (楼主) 6个月前
博学多才的走停 (楼主) 6个月前
lyxxxh (作者) 6个月前
博学多才的走停 (楼主) 6个月前
cnguu 6个月前
讨论数量: 25

switch case 或者工厂模式?

6个月前 评论
博学多才的走停 (楼主) 6个月前

这..就是说 方法名非得要 不一样吗

6个月前 评论
博学多才的走停 (楼主) 6个月前
sanders

我提供两种处理方式。

工厂模式:

  1. 声明个接口,比如 BodyDataHandleable ,里面抽象个方法 handleBodyData(bodyDataValue:BodyDataValue)
  2. 声明5个类分别实现这个接口处理 recordBodyData.setXXXYYY 这些逻辑
  3. 声明个工厂方法用来判断 itemId.equals(EnumBodyData.XXX.name() 获取以上类的实例进行处理,根据语言可用 switch 或 match 语法对 if 结构进行简化

管道模式:

  1. 声明5个类的管道方法,如: handle(bodyDataValue:BodyDataValue, next) 其中 $next 根据语言差异可以是 Function 或 闭包,每个管道方法去实现自己的 if 结构及其处理逻辑
  2. 按顶楼的顺序将类型加入到管道,并依次执行
6个月前 评论
博学多才的走停 (楼主) 6个月前

三个设置写为函数,用switch判断后直接用函数设置

6个月前 评论

多么清晰的代码,有时候反而是负面优化,不要为了优雅而优雅,阳春白雪和下里巴人也是互相存在的。

6个月前 评论
if内的差别只有后面字符串:
recordBodyData.setPbf(bodyDataValue.getValue()):  "pdf" 
recordBodyData.setBmi(bodyDataValue.getValue()) : "Bmi"
recordBodyData.setWt(bodyDataValue.getValue()): "Wt"

那么将字符串作为方法调用即可。



$maps = [
    EnumBodyData.PBF.name() => 'pdf',
    EnumBodyData.BMI.name() => 'Bmi',
    EnumBodyData.WT.name() => 'Wt'
]

for(循环 itemId){
    foreach($maps as $condition_str => $method_str){
        if( itemId.equals($condition_str ) ){
            recordBodyData.{'set' + $method_str}(bodyDataValue.getValue())
            recordBodyData.{'set' + $method_str + 'Ideal'}(bodyDataValue.getValue())
            recordBodyData.{'set' + $method_str + 'Tip'}(bodyDataValue.getValue())
        }
    }
}
ps: 有点忘记php语法 这方案铁定可行的
6个月前 评论
博学多才的走停 (楼主) 6个月前
博学多才的走停 (楼主) 6个月前
lyxxxh (作者) 6个月前
博学多才的走停 (楼主) 6个月前
cnguu 6个月前

多此一举?这代码的可读性不是很高吗?一眼就知道干嘛的

6个月前 评论
博学多才的走停 (楼主) 6个月前

看了sanders的回答,简单问了一下AI工厂类的实现方式,确实代码看起来少了很多。但是总代码量是增加了很多的。要创建整整7个文件。最后实现代码看起来确实优雅很多

for (String itemId : items) {
    EnumBodyData type = EnumBodyData.valueOf(itemId); // 假定itemId是枚举的名字形式
    BodyDataHandler handler = BodyDataFactory.getHandler(type);
    handler.handle(bodyDataValue, recordBodyData);
}
6个月前 评论
梦想星辰大海

recordBodyData是不是封装的有问题,setPbf与setBmi的区别是什么,为什么不是相同的方法名字,不同的recordBodyData对象。

6个月前 评论
博学多才的走停 (楼主) 6个月前

1尽早跳出判断 2代码尽量共用 3使用策略模式(虽然文件多了点,但是维护扩展非常方便)

6个月前 评论

case break吧 早点跳出来 if 给我的感觉每行代码我都要看一下 改到某个逻辑的时候

6个月前 评论

php:7行代码解决 java:7个类解决

6个月前 评论
public enum EnumBodyData {
    PBF, BMI, WT, WHR, BFM;


    public String getSetterMethodName() {
        return name().substring(0, 1).toUpperCase() + name().substring(1) + "Setter";
    }
}
public void updateRecordBodyData(EnumBodyData type, BodyDataValue bodyDataValue, RecordBodyData recordBodyData) {
    switch (type) {
        case PBF:
            setFields(recordBodyData::setPbf, recordBodyData::setPbfIdeal, recordBodyData::setPbfTip, bodyDataValue);
            break;
        case BMI:
            setFields(recordBodyData::setBmi, recordBodyData::setBmiIdeal, recordBodyData::setBmiTip, bodyDataValue);
            break;
        // ... 其他case类似
        default:
            throw new IllegalArgumentException("Unknown type: " + type);
    }
}

private void setFields(Consumer<Double> valueSetter, Consumer<Double> idealSetter, Consumer<String> tipSetter, BodyDataValue bodyDataValue) {
    valueSetter.accept(bodyDataValue.getValue());
    idealSetter.accept(bodyDataValue.getIdealValue());
    tipSetter.accept(bodyDataValue.getTip());
}
6个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!