Передача типа объекта в качестве параметра метода всегда признак плохого дизайна? - PullRequest
0 голосов
/ 31 октября 2018

Предположим, у меня есть следующее перечисление

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 голосов
/ 31 октября 2018

В качестве альтернативы решению Хелвуда (например, в случае, если вы не можете изменить структуру User и Achievement), может иметь смысл считать, что операция извлечения объекта действительно принадлежит 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);
}
0 голосов
/ 31 октября 2018

Вы можете использовать полиморфизм для этого.

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() для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...