Я не могу с тобой больше согласиться. И все же это часто вызывает споры!
Постоянная проблема, с которой мне приходилось сталкиваться в прошлом, — это проблема «слишком много шаблонов»: вы получаете такой код, как:
def reel(self): self._thing.reel() def writhe(self, filename): self._thing.write(filename) def faint_in_coils(self, **kwds): self._thing.faint_in_coils(**kwds)
и это «плохо», потому что если бы вы использовали наследование, его бы не было.
Раньше я в какой-то мере соглашался с этим — «меньше кода — лучше».
Теперь я думаю, что код, подобный приведенному выше, лучше почти каждый раз, потому что я хочу, чтобы все было явным.
Я не хочу многословия, не поймите меня неправильно !, но между этими двумя классами объектов устанавливается связь, и я не хочу просто говорить: Да, да ладно, дай мне все это в родительском «Потому что тогда я обязательно получу то, что мне не нужно, и по мере того, как все растет с течением времени, каждый родительский класс становится« смолистым ребенком (как в ваших примерах).
Я мог бы пойти еще дальше или предложить второе правило — давайте называть его Правилом наименьшего молота, пока я не получу настоящее имя:
«При выборе структуры данных используйте как можно меньший молоток».
Вот молотки:
- Общие, предоставляемые языком контейнеры данных, такие как
tuple
,list
и т. Д. В Python илиstd::vector
и т. Д. В C ++, и бесплатные функции — функции, которые не имеют внутреннего состояния и не ссылаются на изменяемые глобальные переменные. - Обычные старые данные или эквивалент на целевом языке — т.е. данные без методов — и бесплатные функции.
- Новый класс объекта, использующий композицию.
- Новый объектный класс, использующий наследование.
Это не призыв никогда не создавать новый класс, но вы должны выбрать самый маленький молоток, который точно и четко решает проблему, и часто этот молоток будет новым классом. Если вы видите, что ваша конкретная проблема может быть полностью и надежно решена с помощью простых старых данных и бесплатных функций, вы должны быть счастливым разработчиком.
Помните, что бесплатные функции для простых старых данных чрезвычайно легко тестировать, составлять, включать или не включать в проект. Бесплатная функция в файле, который вы никогда не открываете, не добавляет сложности или риска вашему проекту, в отличие от неиспользуемого метода в классе, от которого вы наследуете.