設計模式_裝飾模式


Decorator Pattern 
    Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a  flexible alternative to subclassing for extending functionality.(動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式比生成子類更爲靈活) 

不認識的單詞
dynamically adv 動態的
alternative   n 可供選擇的事務
functionality n 功能

例子
     小時候交成績單給老爸,語文:60  數學:68  自然:87,要知道這樣的成績在小學根本拿不出手,要家長簽名那是不可能的,於是乎需要裝飾一下,就說"這次這次考試語文最高70,數學最高70,自然最高100",完了再加一句,我排名多少等等。。。。。
也就是說,在原來的基礎上再添加倆個功能修飾一下,有人可能會直接使用子類繼承來寫,但是這樣不利於多個,萬一有變,遵循開閉原則,在原來的基礎上再改,該如何實現呢?  

public abstract class SchoolReport {
 public abstract void report();
 public abstract void sign(String name);
}

public class FourthGradeSchoolReport extends SchoolReport {

 @Override
 public void report() {
  System.out.println("尊重的xxx");
  System.out.println("...............");
  System.out.println("語文:60  數學:68  自然:87");
 }

 public void sign(String name) {
  System.out.println("家長簽字:"+name);
 }
}

開始修飾
public abstract class Decorator extends SchoolReport {

 private SchoolReport sr;
 
 public Decorator(SchoolReport sr){
  this.sr=sr;
 }
 
 @Override
 public void report() {
  this.sr.report();
 }

 @Override
 public void sign(String name) {
  this.sr.sign(name);
 }
}
分析Decorator類
    1.爲何要繼承SchoolReport?  如果不繼承的話,下面具體修飾類繼承,並且有一個SchoolReport成員,這樣每次修飾需要把倆個方法都需要實現倆個方法super.xxx(),這樣代碼量增加了。
    2.爲何需要一個SchoolReport成員?  如果沒有,那麼就無法傳遞,實現多層包裝。
ok,搞定了這個,那麼下面就是按照模板來畫圓了。
public class HighScoreDecorator extends Decorator {

 public HighScoreDecorator(SchoolReport sr) {
  super(sr);
 }
 
 private void reportHighScore(){
  System.out.println("這次考試語文最高70,數學最高70,自然最高100");
 }

 @Override
 public void report() {
  this.reportHighScore();
  super.report();
 }
}
public class SortDecorator extends Decorator {

 public SortDecorator(SchoolReport sr) {
  super(sr);
 }
 
 private void reportSort(){
  System.out.println("我排名38");
 }

 @Override
 public void report() {
  super.report();
  this.reportSort();
 }
}

測試
public static void main(String[] args) {
  
  SchoolReport sr;
  sr=new FourthGradeSchoolReport();
  sr=new HighScoreDecorator(sr);
  sr=new SortDecorator(sr);
  sr.report();
  sr.sign("Dad");
  //這樣老爸自然就開心的簽字了
 }

將繼承發揮到了極致,必須要懂重寫的含義,問題不大,一般這樣做的應該不多。

優點
    不會耦合
    動態擴展功能

缺點
    如果最裏面的修飾出現了問題,那麼問題來了,多蛋疼。所以使用的時候儘量減少修飾類的數量,否則...

使用場景
    擴展類功能
    動態的增加類功能
    爲兄弟類進行改裝或加裝

我是菜鳥,我在路上。
發佈了78 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章