组合优于继承(进入设计模式)

Composition over Inheritance(step into Design pattern)

所以我开始学习名为 head first design pattern 的书,在它的第一章中,它给出了一个场景,其中组合优先于鸭子 class 示例。

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

所以上面的鸭子 class 由不同类型的鸭子和一些假橡皮鸭继承。

(基于鸭子类型)

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

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

所以到目前为止看起来还不错。

现在的变化是给鸭子添加飞行行为。

我们不能只给抽象鸭子添加飞行方法行为class,因为有不能飞的假鸭子可用。

因此作者创建了一个 IFly 接口,将由 Flyable class 和 NonFlyable class 实现。

interface IFly
{
 Fly();
}

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

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

所以这个 IFly 接口不会被所有不同的鸭子 class 实现,因为这将是一个巨大的变化,可以为这些鸭子添加 flyable/non 可飞行的行为。所以继承似乎不是一个好主意,同意。

作者建议在 Duck class 内部使用 IFly 接口作为组合。

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 作为某个地方我必须告诉我的每只鸭子 class 它们会飞还是不会正确的??那么,组合实际上是如何解决我无法联系或遗漏的问题的呢??请帮忙

so my questionis how would i know based on type if Flyable functionality to add or NonFlyable as somewhere i have to tell my each and every duck class that either they fly or they not

决定使用哪个 IFly subclass 创建鸭子的代码通常驻留在所谓的 Factory class 中。这种 Factory class 的直接简单实现看起来像:

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 子 classes 应该有一个构造函数,该构造函数采用 Flyable 参数而不是使用 obj.Fly = Flyable 设置它。为此,您可以将这些构造函数添加到 Duck class 本身:

 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
 }

每个鸭子子 classes 然后可以 extend 来自 AbstractDuck 并自动继承构造函数。然后,一个简单的主程序可以通过简单地传递从命令行接收到的类型来创建一个 Duck 实例:

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

So how does composition actually solving the problem

从上面的示例中应该清楚,通过组合,您可以使用名为 MallardDuck 的单个 class 并添加 FlyableNonFlyable 行为而无需必须使 Duck 子 class 的行为强制覆盖。