zoukankan      html  css  js  c++  java
  • 多用组合,少用继承

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

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

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

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

        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方法动态地改变行为了(组合的一大优点)。一般情况下,对象的 多种不同行为 适合 组合 来组织,而 静态的状态,类型等 适合 继承 来组织(这只是一家之说,仅参考)。。。

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    淘宝首页广告圆角切换标签未解之谜(vml)
    chrome的google官方在线安装太坑爹了,找到一个离线下载地址
    kejun写的响应性设计和开发
    HTTP状态码
    xwebkitspeech 语音输入功能
    Avoid Redirects 避免重定向
    webstorm下使用github
    开通了github,用webstorm上传,敲命令行太累。
    jQuery1.6.1下event鼠标事件有BUG,升级到1.7.1可以解决问题。
    从程序员到项目经理(五):不是人人都懂的学习要点
  • 原文地址:https://www.cnblogs.com/hachun/p/3456661.html
Copyright © 2011-2022 走看看