軟體工程 – 設計模式學習之裝飾模式Decorator

來源:互聯網
上載者:User

技術交流,DH講解

如果我們想在不改變已有類的情況下,然後加上新的功能.
這個時候我們就可以使用裝飾模式了.
慣例先看下這個設計模式的UML圖.

裝飾模式關鍵是方法重載.override.
說了這麼多我們來用代碼來說話.

老規矩,第一個是PHP了.
class Person{    var $name='';    function __construct($a){        $this->name=$a;    }    public function show(){
        echo("this is ".$this->name."!!!\n");
    }
}
//穿著的基類
class Finery extends Person{    protected $component;    public function decorator($aPerson){        $this->component=$aPerson;    }    public function show() {        if(isset($this->component))            $this->component->show();    }}//具體的類.
Class Tshirt extends Finery{     public function show() {
         echo("My TShirt@!\n");
         parent::show();
     }
}
//具體類2
class Tie extends Finery{
     public function show(){
        echo("My Tie!!\n");
        parent::show();
     }
}
//Test

   $p = new Person("HuangJacky");
   $tshirt = new Tshirt();
   $tie = new Tie();

   $tshirt->decorator($p);
   $tie->decorator($tshirt);
   $tie->show();
我們看看輸出結果吧.
My Tie!! My TShirt@! this is HuangJacky!!!

我們可以看見關鍵的地方:
parent::show();

接下來我們還是用Java來

class Person{    private String Name;    public Person(){
        this.Name="HuangJacky";
    }
    public Person(String aName){
        this.Name=aName;
    }
    public void show(){
        System.out.println("my name is " + Name + "!\n");
    }
}
class Finery extends Person{    protected Person cmp=null;    public void decorator(Person a){        this.cmp=a;    }    public void show(){        if(cmp!=null)            cmp.show();    }}
class TShirt extends Finery{    public void show(){        System.out.println("My TShirt!\n");        super.show();    }}
class Tie extends Finery{    public void show(){        System.out.println("My Tie!\n");        super.show();    }}class Person{
    private String Name;
    public Person(){
        this.Name="HuangJacky";
    }
    public Person(String aName){
        this.Name=aName;
    }
    public void show(){
        System.out.println("my name is " + Name + "!\n");
    }
}
class Finery extends Person{
    protected Person cmp=null;
    public void decorator(Person a){
        this.cmp=a;
    }
    public void show(){
        if(cmp!=null)
            cmp.show();
    }
}
class TShirt extends Finery{
    public void show(){
        System.out.println("My TShirt!\n");
        super.show();
    }
}
class Tie extends Finery{
    public void show(){
        System.out.println("My Tie!\n");
        super.show();
    }
}
public class Main {
    public static void main(String[] args) {
        Person p = new Person("TheFiend");
        TShirt t = new TShirt();
        Tie T = new Tie();
        t.decorator(p);
        T.decorator(t);
        T.show();
    }
}

其實代碼都是一樣,只是語言不同而已.
super.show();
在C#裡面我們就需要改成base.show();

最後進入Delphi Time.
Type
TPerson = Class
Private
Name: String;
Public
Constructor Create( Const AName: String );
Procedure Show( ); Virtual;
End;
TFinery = Class( TPerson )
Private
FPerson: TPerson;
Public
Procedure Show( ); Override;
Property Person: TPerson Read FPerson Write FPerson;
End;
TTShirt = Class( TFinery )
Public
Procedure Show( ); Override;
End;
TTie = Class( TFinery )
Public
Procedure Show( ); Override;
End;
{ TPerson }
Constructor TPerson.Create( Const AName: String );
Begin
Self.Name := AName;
End;
Procedure TPerson.Show;
Begin
Writeln( 'my name is ' + Name );
End;
{ TFinery }
Procedure TFinery.Show;
Begin
If Assigned( FPerson ) Then
FPerson.Show;
End;
{ TTShirt }
Procedure TTShirt.Show;
Begin
Writeln( 'My Shirt' );
Inherited;
End;
{ TTie }
Procedure TTie.Show;
Begin
Writeln( 'My Tie!' );
Inherited;
End;
測試:
Var
P: TPerson;
T: TTShirt;
I: TTie;
S: String;
Begin
P := TPerson.Create( 'HuangJacky' );
T := TTShirt.Create( '' );
I := TTie.Create( '' );
T.Person := P;
I.Person := T;
I.Show;
Readln( S );
End.
OK,Delphi也是這樣的.
我們可以看到Delphi裡面是一句Inherited;因為調用的是父類的同名同參數的函數 所以函數名可以省略掉.不然就要寫成
Inherited show();了

總結下,裝飾模式適用的情況:

  • 在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。
  • 處理那些可以撤消的職責。
  • 當不能採用產生子類的方法進行擴充時。一種情況是,可能有大量獨立的擴充,
  • 為支援每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。
  • 另一種情況可能是因為類定義被隱藏,或類定義不能用於產生子類。

就到這裡,我是DH.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.