Я хочу спросить кое-что о примере утки в этой книге, которая смутила меня, и я чувствую противоречия.
проблема
выводы
Он сказал, что « когда Джо добавил новое поведение к суперклассу утки, он также добавил поведение, которое не было подходящим для подклассов suum Duck »
НО в заключении он добавил performFly()
и performQuack();
что такое другое, потому что я думаю, что это было так же, когда he was also adding behavior that was not appropiate for sume Duck subclasses
?
** изображение, взятое из книги Глава первая схема дизайна ** этот вопрос не говорит, что эта книга не очень хорошая, эта книга действительно хороша, на мой взгляд. это только я, кто спрашивает то, что я не получил от книги.
В заключении он добавляет два новых класса, у которых есть функция fly()
. Однако функция не всегда делает утиную муху. Резиновые утки не могут летать, поэтому они используют экземпляр класса FlyNoWay
. Другие утки, которые могут летать, используют экземпляр класса FlyWithWings
. Поле flyBehavior
в классе Duck
, вероятно, будет установлено в конструкторе.
Функция performFly()
вызовет функцию fly()
для любого класса.
Как указано в комментариях, это довольно сложное решение. Однако его все еще можно использовать. Скажите, что вы создаете программу проектирования уток. Если пользователь выбирает, может ли утка летать, она не может быть жестко закодирована. Вы можете создать логическое значение, но вам, возможно, придется обрабатывать более сложные ситуации, такие как поведение. Вам может понадобиться класс WildDuckBehavior
и DomesticDuckBehavior
, каждый со своей информацией о том, как действовать. В принципе, пример в книге представляет собой упрощенную версию того, как это будет использоваться.
Шаблон стратегии работает, если вы предпочитаете композицию над наследованием http://en.wikipedia.org/wiki/Composition_over_inheritance
Это хорошая практика, потому что вы можете изменить поведение класса без изменения какого-либо кода. И вам также не нужно огромное дерево классов. Вы также динамически изменяете поведение класса.
Что он делает в этом примере, это определение «поведения» в родительском классе. В родительском классе вы определяете, что утка может иметь летающее поведение и поведение шарлатанов. Но это не означает, что классы детей должны иметь шарлатанство или летать.
У вас может быть нелетучая утка, и когда вы называете «летать», она ничего не сделает, потому что у нас будет «нелетающее» поведение.
Вместо жесткого кодирования, что делает утка в классе, вы можете изменить поведение этой утки, когда захотите.
Я не гуру шаблонов дизайна, но пока я читал эту книгу, первое ощущение, которое у меня было в этой конкретной главе, было то, что интерфейс был построен, а затем реализован, нарушил один из хорошо известных принципов программирования: разделение интерфейса Принцип (ISP) В основном этот принцип гласит, что
ни один клиент не должен зависеть от методов, которые он не использует
Потому что некоторые утки, которые не летают, реализуют метод fly (), даже если они им не нужны. Тем не менее, я думаю, что в этом конкретном случае неизбежно реализовать все методы интерфейсов, поскольку на стороне клиента мы используем полиморфное поведение, и мы должны быть уверены, что у нас есть все доступные методы, даже если они не используются.