Композиция над наследованием (шаг в шаблон проектирования) - PullRequest
0 голосов
/ 19 октября 2019

Итак, я начал изучать книгу, которая называется «шаблон проектирования головы», и в ее начальной главе был приведен сценарий, в котором композиция предпочтительнее, чем унаследование, на примере класса утки. различными типами уток, а также ненастоящей резиновой уткой.

(в зависимости от типа утки)

      Duck obj=new IndoDuck();
         //Or
     //Duck obj =new MallardDuck();

     obj.Swim();
     obj.Look();

Так что до сих пор это выглядит хорошо.

Теперь пришло изменение, добавив к уткам поведение Flying.

Мы не можем просто добавить поведение метода fly к абстрактному классу утки, так как существуют поддельные утки, которые не могут летать.

Поэтому автор создает интерфейс IFly, который будет реализован классом Flyable и классом NonFlyable.

interface IFly
{
 Fly();
}

Flyable: IFly
{
 Fly()
{
  // can fly
}
}

NonFlyable:IFly
{
 Fly()
{
  // cant fly
}
}

Так что этот интерфейс IFly не будет реализован всеми различными классами уток, так как это будет серьезным изменением для добавления flyable/ Нелетное поведение к этим уткам. Так что уныние кажется не очень хорошей идеей, согласитесь.

Автор предполагает, что интерфейс IFly будет использоваться внутри класса Duck в качестве композиции.

public abstract class Duck
{
   Swim()
       { 
          //all ducks can swim same way
       }
   abstract Look();// ducks can look different

IFly Fly();
}

Так что теперь я могу это сделать.

      Duck obj=new IndoDuck();
         //Or
     //Duck obj =new MallardDuck();

     obj.Swim();
     obj.Look();
obj.Fly =new Flyable();
//or
obj.Fly=new NonFlyable();

поэтому мой вопрос в том, как бы я узнал, основываясь на типе, если функциональность Flyable добавить или NonFlyable, как где-нибудь, я должен сказать каждому классу утки, что они либо летают, либо не правы ?? Так как же композиция действительно решает проблему, которую я здесь не могу связать, или я что-то пропустил? Пожалуйста, помогите.

1 Ответ

0 голосов
/ 19 октября 2019

поэтому мой вопрос в том, как я узнаю, основываясь на типе, если функциональность Flyable добавить или NonFlyable, как где-то, я должен сказать каждому классу утки, что они летают или нет

* 1004Код, который принимает решение о том, с каким IFly подклассом создавать утку, обычно находится в классе, известном как Factory . Простая и простая реализация такого класса Factory будет выглядеть примерно так:
public class DuckFactory {
    public static Duck createDuck(DuckType type) {
         if(DuckType.FlyableMallard.equals(type)) {
              return new MallardDuck();
         } else if(DuckType.Mallard.equals(type)) {
              return new MallardDuck(new NonFlyable());
         }
    }
}

Обратите внимание, что подклассы Duck должны иметь конструктор, который принимает аргумент Flyableвместо того, чтобы устанавливать его с помощью obj.Fly = Flyable. Чтобы достичь этого, вы можете добавить эти конструкторы к самому классу Duck:

 public abstract class Duck {
       protected IFly flyBehavior;
       public AbstractDuck(IFly flyBehavior) {
            this.flyBehavior = flyBehavior;
       }

       public AbstractDuck() {
            //all ducks can fly by default
            this.flyBehavior = new Flyable();
       }

       protected abstract void look();
       //other methods
 }

Каждый из подклассов утки может затем extend из AbstractDuck и автоматически наследовать конструкторы. Затем простая основная программа может создать экземпляр Duck, просто передав тип, полученный из командной строки:

DuckType duckType = [duck type recieved as program input]
Duck duck  = DuckFactory.create(duckType);

Так как же на самом деле решение проблемы решает композиция

Из приведенного выше примера должно быть ясно, что с композицией вы можете использовать один класс с именем MallardDuck и добавить поведение Flyable или NonFlyable без необходимости делать поведение обязательным для подклассов Duckпереопределить.

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