【问题标题】:Refactoring code into function by mapping通过映射将代码重构为函数
【发布时间】:2013-09-29 08:24:28
【问题描述】:

我有以下代码:

...
if (...) { // Handling emails
  int emailType = -1; 
  if (types != null) {
    String type = foo(types);
    if (type.equals("work")) {
      emailType = Email.TYPE_WORK;  // android.provider.ContactsContract.CommonDataKinds.Email
    } else if (type.equals("home")) {
      veemailType = Email.TYPE_HOME;
    } else if (type.equals("mobile")) {
      emailType = Email.TYPE_MOBILE;
    } else if (type.equals("other")) {
      emailType = Email.TYPE_OTHER;
    }
    bar(emailType);
  }
} else if (...) { // Handling phones
  int telType = -1; 
  if (types != null) {
    String type = foo(types);
    if (type.equals("work")) {
      telType = Phone.TYPE_WORK;  // android.provider.ContactsContract.CommonDataKinds.Phone
    } else if (type.equals("home")) {
      telType = Phone.TYPE_HOME;
    } else if (type.equals("mobile")) {
      telType = Phone.TYPE_MOBILE;
    } else if (type.equals("other")) {
      telType = Phone.TYPE_OTHER;
    }
    bar(telType);
  }
} else if ...

显然我应该使用一个函数来包装这些类似的处理逻辑,但不知道该怎么做。

C/C++ 在这种情况下我更喜欢宏,但看起来 Java 中没有宏?

【问题讨论】:

    标签: java function macros refactoring


    【解决方案1】:

    您应该创建一个从电子邮件类型的字符串版本到 Email.TYPE_* 的 HashMap。

    然后你可以将地图传递给一个函数,例如

    int clean(Map<String, Integer> typemap, String type_s) {
        return bar(typemap.get(foo(type_s)));
    } 
    

    【讨论】:

    • 你能详细说明如何创建这样的HashMap吗?谢谢。
    【解决方案2】:

    您需要编写处理电话和处理电子邮件的方法。您应该切换 case 语句,而不是使用 if else 循环。我建议安装各种代码质量插件,它们会在您编写 Java 代码时指出您的代码质量问题

    【讨论】:

    • 问题是,如果我编写方法,看起来我必须将很多内容传递给方法,例如Phone.TYPE_WORK, Phone.TYPE_HOME, Phone.TYPE_MOBILE, Phone.TYPE_OTHER, ...。知道如何避免这种情况吗?
    • 创建一个具有各种值的公共枚举电话。由于它是公开的,因此您也可以在您的方法中访问它。
    【解决方案3】:

    这里的一个选择是摆脱 int 常量并引入带有工厂方法的 enum 类以从字符串中生成值:

    public enum Email{
        TYPE_HOME("home"),
        TYPE_MOBILE("mobile"),
        TYPE_OTHER("other"),
        TYPE_WORK("work");
    
        private final String stringValue;
    
        Email(String stringValue) {
            this.stringValue = stringValue;
        }
    
        public static Email parse(String value){
            for (Email email : values()){
                if (email.stringValue.equals(value)){
                    return email;
                }
            }
            throw new IllegalArgumentException("Illegal argument: " + value);
        }
    }
    

    现在您可以将 if-else 链替换为以下内容:

    String types = foo(types);
    Email email = Email.parse(types);
    bar(email);
    

    【讨论】:

    • 外部 API 需要 int,在这种情况下是 android 内容提供程序,所以这不起作用。
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 2020-01-05
    相关资源
    最近更新 更多