将对象类型作为方法参数传递总是表明设计不佳吗?

时间:2018-10-31 15:42:23

标签: java oop

假设我有以下枚举

public enum EmailType {
    FORGET_PASSWORD, ACHIEVMENT_UNLOCK, WELCOME
}

并且我有一个功能可以根据类型(例如,仍然需要动态数据)生成电子邮件主题,例如

public String generateEmailSubject(EmailType emailType, Object obj) {
    String subject;
    switch(emailType) {
        case WELCOME:
            User user = (User) obj;
            subject = "Hello " + user.getFirstName();
        case FORGET_PASSWORD:
            User user = (User) obj;
            subject = "Forget password " + user.getEmail();
            break;
        case ACHIEVMENT_UNLOCK:
            Achievment achievment = (Achievment) obj;
            subject = "Achievment Unlock:" + achievment.getTitle();
            break;
    }

    return subject;
}

这是不好的做法吗?如果是这样,有什么好的设计来解决这个问题?也许每个EmailType都有一个单独的方法,但这可能导致很多方法,并且当我需要更改主题时,这些主题将不会集中。

2 个答案:

答案 0 :(得分:2)

您可以为此使用多态性。

interface Subjectable {
    String getSubject();
}

class Achievement implements Subjectable {
    ...
    @Override
    public String getSubject() {
        return "Achievement unlocked: " + getTitle();
    }
}

class User implements Subjectable {
    ...
    @Override
    public String getSubject() {
        return "Forgot password: " + getEmail();
    }
}

然后,您无需显式检查对象的类型:只需在其上调用getSubject()

答案 1 :(得分:1)

作为凯尔伍德解决方案的替代方法(例如,在无法更改UserAchievement的结构的情况下),有可能考虑到主题提取操作确实属于与EmailType。如果EmailType具有generateEmailSubject方法,则将形成一个更具凝聚力的单元,而不是在逻辑单元和当前定义的任何类generateEmailSubject()之间散布逻辑。

public enum EmailType {

    FORGET_PASSWORD {
        @Override
        public String generateEmailSubject(Object obj) {
            User user = (User) obj;
            return "Forget password " + user.getEmail();
        }
    },

    ACHIEVMENT_UNLOCK {
        @Override
        public String generateEmailSubject(Object obj) {
            Achievment achievment = (Achievment) obj;
            return "Achievment Unlock:" + achievment.getTitle();
        }
    };

    public abstract String generateEmailSubject(Object obj);
}