2008年10月23日 星期四

OOAD(12): 三種不使用繼承的好方法

如果不透過繼承,又希望從別的類別得到好處。可使用

  1. Delegation (委派)
  2. Composition
  3. Aggreation

Delegation (委派)

一台轎車,如果想要可以欣賞音樂的能力,不是透過繼承(畢竟車子不是音響),而是在車子內加裝汽車音響。
因此,轎車內需要放音樂的能力時,只需要打開汽車音響即可。
class 轎車
{
  private 汽車音響 a汽車音響 = new 汽車音響();
  public void 欣賞音樂()
  {
    a汽車音響.打開();
  }
}

或者,隨時找到一台音響再打開

class 轎車

  public void 欣賞音樂()
  {

    汽車音響 a汽車音響 = new 汽車音響(); //隨時想有就可以有?這大概是軟體世界才有的能力
    a汽車音響.打開();
  }
}

Composition

一個士兵,需要有攻擊的能力,但士兵畢竟不是武器,因此士兵需要有武器。到目前為止就像委派。
但是,武器有許多種,如飛彈、槍、劍,每一種的攻擊方式都不同。

注意到 weapon 是可替換的,只要有實作 IWeapon 的武器就可以。換句話說,一整族IWeapon的武器都可以替換。
另外,weapon 是天生就存在於 Soldier 內的。一旦 Soldier 被 destoryed, weapon 就不存在了。

class Soldier
{
    private IWeapon weapon = new Sword();
    public void Attack()
    {
      weapon.Attack();
    }
  }

  interface IWeapon
  {
    void Attack();
  }

  class Sword : IWeapon
  {
    public void Attack() { }
  }

Aggregation

aggregation 與 Composition 類似,但結構更鬆散,更容易 resuse。上述的例子,weapon 只能生存在 Soldier 的生命週期內,並不合理。如果改成下面的例子,就是 aggregation 了。注意到 weapon 是由建構子傳進去的。當soldier1 被destoryed 後,sword 並不隨之消減。也就是說,可以被 soldier2 再拿去用。

class Soldier
  {
    private IWeapon weapon;
    public Soldier(IWeapon weapon)
    {
      this.weapon = weapon;
    }
    public void Attack()
    {
      weapon.Attack();
    }
  }

  interface IWeapon
  {
    void Attack();
  }

  class Sword : IWeapon
  {
    public void Attack() { }
  }

class Program
  {
    static void Main(string[] args)
    {
      Sword sword = new Sword();
      Soldier soldier1 = new Soldier(sword);
      soldier1.Attack();
    }
  }


在日常生活上,Aggreation 遠較 Composition 多見,這同時也反應到軟體工程上。畢竟物件導向工程是模擬真實的世界。

1 則留言:

匿名 提到...

我想請問:

Delegation (委派) 舉的例子中,車子不是也能有有許多種音響??

那跟 Composition 中舉的士兵需要有攻擊的能力,士兵需要有武器,

武器有很多種,差在哪裡呢??

我分不清楚 Delegation & Composition 間的差別,

麻煩您指點指點,

By 想要弄明白的我

Share with Facebook