简体   繁体   中英

Is passing Object type as a method parameter always a sign of poor design?

Assume I have the following enum

public enum EmailType {
    FORGET_PASSWORD, ACHIEVMENT_UNLOCK, WELCOME
}

and I have a function that generates email subjects based on the type (but it still requires dynamic data), eg

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;
}

Is this bad practice? If so, what's a good design to handle this? Maybe a separate method for each EmailType but that could lead to a lot of methods and the subjects will not be centralized when I need to change them.

You could use polymorphism for this.

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();
    }
}

Then you don't need to explicitly check the type of the object: you just call getSubject() on it.

As an alternative to khelwood's solution (in case, for example, you can't change the structure of User and Achievement ), it may make sense to consider that the subject extraction operation really belongs with EmailType . If EmailType has the generateEmailSubject method, that would make a more cohesive unit instead of having the logic spread between it and whatever class currently defines 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM