一般情况下,继承(主要是由类实现)可能比组合(主要是由接口实现)更好实现,而且继承似乎有种一劳永逸的牛叉功能。这篇随笔是我读过一篇文章之后的一些想法,欢迎各位指教讨论。

  一般情况下,我们总是花许多时间在系统的维护和变化上,有时会比开发花的时间更多,所以我们应该致力于提高可维护性和可扩展性上的复用程度,而继承在这方面可能略逊于组合,当然也有特殊情况。。。

  使用组合建立的系统具有很大的弹性,不仅可以将算法族封装成类,更可以在运行时动态地改变行为,只要组合的行为对象符合正确的接口标准即可。

  下面用一些代码来具体说说。。。还是用策略模式中的例子。

    public abstract class Cat
  {
    IEatBehavior pEatBehavior;   // 为行为接口定义一个引用变量
    public void Eat()
    {
      pEatBehavior.Eat(); 
    }
    public void Drink()
    {
      System.Out.Println(" I Drink Water.");
    }
  }
  public class WhiteCat Extends Cat
  {
    public WhiteCat()
    {
      pEatBehavior = new WhiteCatEatBehaviorClass();   // WhiteCatEatBehaviorClass 是实现接口 IEatBehavior 的一个具体类,
                                      // 里面的细节可以不用管,
                                     // 你只需要知道这是白猫特有的吃法就行了                              
    }
  } 

 

  现在白猫也有自己 不同于 超类中的喝,如果使用继承的话,只要覆盖超类中的方法Drink()即可,但想一想,如果有很多子类继承该超类呢,那就得一个一个的覆盖,这可是体力活了。。。所以觉得在这使用组合可能更合适一点,现在就干起来,首先来新建一个含有Drink()方法的接口和一些具体类 

    public interface IDrinkBehavior
  {
    public Drink();
  }
  public class WhiteCatDrinkBehavior implements IDrinkBehavior
  {
    public void Drink()
    {
      System.Out.Println(" I Drink Soup.");
    }
  }

 

  下面让我们再重新写一下超类及它的子类

    public abstract class Cat
  {
    IEatBehavior pEatBehavior;         // 为吃行为接口定义一个引用变量
    IDrinkBehavior pDrinkBehavior;     // 为喝行为接口定义一个引用变量,有了这个变量,原来的Drink()方法就可以简化了
    public void Eat()
    {
      pEatBehavior.Eat();
    }
    public void Drink()
    {
      pDrinkBehavior.Drink();       // 直接委托给 pDrinkBehavior 对象办就可以了
    }
  }
  public class WhiteCat Extends Cat
  {
    public WhiteCat()
    {
      pEatBehavior   = new WhiteCatEatBehaviorClass(); 
      pDrinkBehavior = new WhiteCatDrinkBehaviorClass();    // 实例化一下,指明 喝 这个行为委托给哪个具体类来执行
    }
  }

 

  上面提到了可以在运行时动态地改变行为,这里也介绍一下实现方法,我们可以在超类中,加入两个方法:

  

public abstract class Cat
{
    // 之前的方法,变量不变
    // 添加的方法

    public Void SetEatBehavior(IEatBehavior pNewEatBehavior)
    {
        pEatBehavior = pNewEatBehavior;
    }

    public Void SetDrinkBehavior(IDrinkBehavior pNewDrinkBehavior)
    {
        pDrinkBehavior = pNewDrinkBehavior;
    }
}

 

  这样就可以在运行时调用SetEatBehavior,SetDrinkBehavior方法动态地改变行为了(组合的一大优点)。一般情况下,对象的 多种不同行为 适合 组合 来组织,而 静态的状态,类型等 适合 继承 来组织(这只是一家之说,仅参考)。。。

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2013-12-03 22:33  花爱春  阅读(863)  评论(0编辑  收藏  举报