`
wgcode
  • 浏览: 576915 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

OOP的聚合原则

 
阅读更多

什么是聚合?


    聚合可以很好地表达对象是什么和做什么。换句话说,聚合是把执行同一任务的代码整合到一起。
    关于聚合原则,在Gamedevtuts+以前的文章里,有一篇关于“隐藏行动规则”的非编程文章,里面的例子讲的很好,可以参考。

    不要把很多游戏捆版在一个包里… 每个单独的游戏可能都是一个好游戏。如果放在一起,他们就会彼此不相容。
    这一原则同样适用于面向对象编程。每个对象应该只有一个职责,对象的每个行为应该只做一个任务。只要超出了范围,代码的维护就会增加工作量。

 

为什么有用?

    按照功能来组织的,只执行单一任务的代码,被称为具有“高聚合”。高聚合的代码是可重用的,单纯的,易懂的。高聚合也使对象更精悍,功能更集中。
    相反的,随意组织起来,执行多个任务的代码,被称为“低聚合”。这样的代码不好理解,不易维护和重用,一般比较复杂。低聚合创建的对象臃肿,且功能散乱。
     
高聚合显而易见是好的,低聚合则很差。所以我们编程时一定要力求做到高聚合。

 

如何应用

    那么我们如何把高聚合原则应用到面向对象编程里? 首先,用对象的方式编程就是对聚合性的提高。当然每个对象本身也应该有高聚合性。我们同样用上篇文章里的三个游戏例子来看聚合原则是如何应用的。
小行星游戏(Asteroids)
    回想一下上一课,我们定义了飞船这个对象,它具有旋转,移动,开火等行为。
    如果我们在一段代码里把三个行为都写在一起,就会显得很混乱。所以我们应该把每个行为都分开用函数来定义。函数可以分离功能,把相关的代码组合在一起,创建高聚合的程序。
    在程序里,我们通过创建类来定义对象。Java语言里类的代码就像这样: 

 

/**

* 飞船类

*/

public class Ship {

    /**

    * 函数– 执行旋转飞船的行为(任务)

    */

    public void rotate() {

    // 旋转飞船的代码

    }

    /**

    *函数–执行移动飞船的行为(任务)

    */

    public void move() {

    //移动飞船的代码

    }

    /**

    *函数–执行移动飞船开火射击的行为(任务)

    */

    public void fire() {

    //飞船发射子弹的代码

    }

}
 

就像你看到的,每个行为都有一个函数,而程序代码在这个简略结构里被很好的组织起来了。
    先不用担心具体的语法,在这个教程系列后面的部分,我们会讨论到具体的程序细节。
俄罗斯方块(Tetris)
    再回想一下俄罗斯方块游戏,俄罗斯方块这个对象具有下落,左右移动,旋转三个行为。基本的类结构如下:。

 

 

/**

* 俄罗斯方块游戏类

*/

public class Tetromino {

    /**

    * 函数 – 更新方块的位置

    */

    public void fall() {

    //更新方块位置的代码

    }

    /**

    *函数 – 左右移动方块

    */

    public void move() {

    //左右移动方块的代码

    }

    /**

    *函数 – 旋转方块

    */

    public void rotate() {

    //旋转方块的代码

    }

}

 

 

同样的,对象的行为都被分到各自的函数。你可能注意到了,“下落”这个方法执行的是“更新方块的位置”。这是因为下落的行为是一直在持续发生的,而不是一次性触发的,所以我们不能只执行“让方块下落”这样的任务。下落的方块每次向下移动一定的位移量,所以我们通过更新方块的位置来反映下落速度。

 

 

吃豆人(Pac-Man)
    “鬼”这个对象有移动和改变状态两种行为,对它我们还要增加一些东西来实现高聚合。

/**

* “鬼”的类

*/

public class Ghost {

    /**

    * 函数 – 移动鬼

    */

    public void move() {

    // 鬼以当前方向移动的代码

    }

    /**

    *函数- 改变鬼的方向

    */

    public void changeDirection() {

    //改变鬼方向的代码

    }

    /**

    *函数- 改变鬼的速度

    */

   public void changeSpeed() {

    //改变鬼速度的代码

    }

    /**

    *函数- 改变鬼的颜色

    */

    public void changeColor() {

    //改变鬼颜色的代码

   }

    /**

    *函数- 改变鬼的状态

    */

    public void changeState() {

    //改变鬼状态的代码

    //这个函数会调用其他三个函数:改变鬼的方向,改变鬼的速度,改变鬼的颜色

    }

}

 

 

更改鬼的状态额外增加了三个函数: 改变方向,改变颜色,改变速度。这三个函数不在我们开始的行为列表里,因为它们其实不是对象的行为。这些函数被称为“辅助函数”,它们有助于程序维持高聚合。
    鬼改变状态(当吃豆人吃到超能豆的时候)这一行为需要执行三个任务:变成蓝色,调转方向,移动变慢。要维持高聚合,所以我们就不要把三个任务放在同一个函数里。我们把它们分到三个子函数里,最后在一个主函数里统一调用。
    在描述函数/或者行为时常用到“and”,它的意思就是告诉我们应该创建更多的函数来执行任务。

总之,聚合原则就是要把相关的代码组织在一起,执行单一的任务。聚合帮助我们创建可维护的,可重用的代码。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics