Например, предположим, у меня есть класс для расширения других классов:
public class LoginPage {
public String userId;
public String session;
public boolean checkSessionValid() {
}
}
и некоторые подклассы:
public class HomePage extends LoginPage {
}
public class EditInfoPage extends LoginPage {
}
На самом деле, у подкласса нет никаких методов для переопределения, также я бы не стал обращаться к HomePage в общем виде, то есть: я бы не делал что-то вроде:
for (int i = 0; i < loginPages.length; i++) {
loginPages[i].doSomething();
}
Я просто хочу повторно использовать страницу входа. Но согласно https://stackoverflow.com/a/53354 , я бы предпочел композицию здесь, потому что мне не нужен интерфейс LoginPage, поэтому я не использую здесь наследование:
public class HomePage {
public LoginPage loginPage;
}
public class EditInfoPage {
public LoginPage loginPage;
}
но проблема возникает здесь, в новой версии, код:
public LoginPage loginPage;
дублируется при добавлении нового класса. И если LoginPage нужны сеттер и геттер, нужно скопировать больше кодов:
public LoginPage loginPage;
private LoginPage getLoginPage() {
return this.loginPage;
}
private void setLoginPage(LoginPage loginPage) {
this.loginPage = loginPage;
}
Таким образом, мой вопрос заключается в том, нарушает ли «композиция через наследование» «сухой принцип»?
extends LoginPage
повсюду дубликаты . МАТ!
LoginPage
- декоратором. Нет больше дублирования, просто page = new LoginPage(new EditInfoPage())
и все готово. Или вы используете принцип open-closed для создания модуля аутентификации, который можно динамически добавлять на любую страницу. Существует множество способов справиться с дублированием кода, в основном с помощью поиска новой абстракции. LoginPage
скорее всего, это плохое имя, и вы хотите убедиться, что пользователь проходит аутентификацию при просмотре этой страницы, перенаправляется на LoginPage
или показывает правильное сообщение об ошибке, если это не так.