Как уменьшить дублирование кода с настройкой частных переменных без использования наследования?

У меня есть классы MonthTimeCard и MonthReport. Они используют одно и то же поле ввода для выбора месяца, поэтому проверка одинакова, а инициализация одинакова.

class MonthTimeCard {

private function setPrivateVarsByUserInput()
{
$this->month_from_input = '2015-09';

$this->date_from = '2015-09-01';
$this->date_to = '2015-09-30';

// lets say those 3 values are formated, validated and returned as array from MonthUserInput class.
// but I have to repeat code in my both classes to initialize them
// I could have one liner like $this->data = $this->monthUserInput->getInput();
// but current class code will need to call $this->data->[variable] everywhere - not looking very nice,
// because ->data is not usefull here, just extra characters.
}

}

Class MonthReport {
... same initialisation
}

Сейчас я просто жестко запрограммировал их, но вы знаете, что присвоение будет из возвращаемого массива класса MonthUserInput, который будет проверяться. Существует только одно поле ввода пользователя, которое получает строку типа «2015-09», а класс MonthUserInput добавит первый день и последний день месяца.

Я мог бы избежать этого, если бы использовал наследование, но я прочитал, что следует избегать, а некоторые даже говорят, что его следует удалить из ООП.

http://blogs.perl.org/users/sid_burn/2014/03/inheritance-is-bad-code-reuse-part-1.html

С наследованием я бы просто сделал проверку и настройку пользовательского ввода в родительском классе и поэтому не дублировал.

Как я должен сделать это сейчас? Конечно, в этом примере только 3 переменные, я планирую иметь 5, это не так много, но все же его дублирование и с наследованием в этом случае дублирования не будет.

Обновить

Я хотел бы видеть объяснение, которое я мог бы использовать, чтобы объяснить любому, кто не согласен с тем, что наследование было бы плохо в этой ситуации. Например, я обсуждал с одним опытным программистом, и он не видит здесь проблемы в использовании наследования для повторного использования кода. Я только что сказал, что в Интернете много говорят о том, что используют композицию, но это не было хорошим аргументом в этой ситуации.

Например:

Подарите композицию наследству. Если два класса не имеют «это
«отношения, то никогда не должно быть необходимости использовать наследование
добиться повторного использования кода. Никогда.

это не будет хорошим аргументом для некоторых людей. Они могут спросить — кто изобрел эти правила и почему? Они не видят проблемы, нарушая это правило.

0

Решение

Наследование является мощным инструментом и может обеспечить повторное использование кода, однако оно несет в себе потенциальные проблемы и должно использоваться соответствующим образом. Потому что подклассы зависеть на реализацию суперкласса, наследование нарушает инкапсуляцию и может сделать код более хрупким и сложным в обслуживании.

Достигните дисциплины, чтобы использовать наследование только когда действительно есть отношения «есть», например. PreferredClient — это клиент … или … MountainBike — это велосипед. Если вы разрабатываете класс, который не достигает отношения IS A с намеченным суперклассом, то не используйте наследование.

Вы можете достичь такой же степени повторного использования кода, используя состав вместо наследования. Вместо создания подкласса, включите предполагаемый суперкласс в качестве атрибута вашего класса. Это позволяет делегировать вызовы методов содержащемуся экземпляру и достигать повторного использования кода.

Для вашего примера кода предложенная декомпозиция кода может быть такой:

class MonthTimeCard {

Month myMonth;

MonthTimeCard(Month month) { myMonth = month; }

private function setPrivateVarsByUserInput()  {
// calls to myMonth
}

}

Class MonthReport {
// calls to myMonth
}

Class Month {
$this->month_from_input = ...

$this->date_from = ...
$this->date_to = ...
}
1

Другие решения

Если MonthTimeCard а также MonthReport не логически расширять друг друга (например, Dog а также Cat являются подтипами Animal), это не очень хорошая идея использовать наследование здесь в любом случае.

Кроме того, если вы выполняете одну и ту же проверку в нескольких местах, вы можете ввести отдельную DateValidator Класс и использовать это всякий раз, когда требуется.

public class DateValidator {

public static boolean validate(final String dateString) {
return ...; // TODO: Validate user input here
}

}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector