六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

Decorator模式中遭遇繼承與聚合

[摘要]一:背景:Decorator   *Decorator 常被翻譯成"裝飾",我覺得翻譯成"油漆工"更形象點,油漆工(decorator)是用來刷油漆的,那么被刷油漆的對象我們稱decoratee.這兩種實體在Decorator 模式中是必須的。   *Dec...
一:背景:Decorator

  *Decorator 常被翻譯成"裝飾",我覺得翻譯成"油漆工"更形象點,油漆工(decorator)是用來刷油漆的,那么被刷油漆的對象我們稱decoratee.這兩種實體在Decorator 模式中是必須的。

  *Decorator 定義:

  動態給一個對象添加一些額外的職責,就象在墻上刷油漆.使用Decorator 模式相比用生成子類方式達到功能的擴充顯得更為靈活。

  *為什么使用Decorator?

  我們通常可以使用繼承來實現功能的拓展,如果這些需要拓展的功能的種類很繁多,那么勢必生成很多子類,增加系統的復雜性,同時,使用繼承實現功能拓展,我們必須可預見這些拓展功能,這些功能是編譯時就確定了,是靜態的。

  使用Decorator 的理由是:這些功能需要由用戶動態決定加入的方式和時機.Decorator 提供了"即插即用"的方法,在運行期間決定何時增加何種功能。

  *對于該模式,初步歸納為

  1.基本功能為接口

  2.Decorator參數為接口本身也為接口以便為下一個Decorator的參數

  3.基本功能類實現接口 并作為Decorator構造函數的參數,以便在此基礎上添加新功能

  4.額外功能由Decorator中的數據結構處理
  
  二:問題

  這是一段Decorator設計模式的實現例子如下:

  基本功能:Counter類
  需要添加的功能

  1:上限控制

  2:下限控制

  import java.io.*;
  class Counter{
  private int value;
  public Counter(int v){
  System.out.println("init me here in The Counter with value!");
  value=v;
  }

  public Counter(Counter cc){
  System.out.println("init me here in The Counter with class!");
  value=cc.value;
  }

  public int read_value(){
  System.out.println("read me here The value is:"+value);
  System.out.println("read me here in The Counter!");

  return value;
  }

  public void increment(){
  System.out.println("increment me here in The Counter !");
  value++;
  }

  public void decrement(){
  System.out.println("decrement me here in The Counter !");
  value--;
  }
  }

  class Decorator extends Counter
  {
  Counter counter;
  public Decorator(Counter c)
  {
  super(c);
  System.out.println("init me here with class Decorator!");
  } 
  }

  class UpperLimit extends Decorator//上限控制
  {
  public UpperLimit(Counter c)
  {
  super(c);
  counter=c;
  System.out.println("init me here with class UpperLimit!");
  }
  public void increment()
  {
  if(counter.read_value()>20)
  {
   System.out.println("Too High");
  }
  else
  {
   System.out.println("increment me here with class UpperLimit!");
   counter.increment();
  }
  }
  /*public void decrement()
  {
  counter.decrement();
  }
  public int read_value()
  {
  return counter.read_value();
  }*/

  }

  class LowerLimit extends Decorator//下限控制
  {
  public LowerLimit(Counter c)
  {
  super(c);
  counter=c;
  System.out.println("init me here in The Counter with class LowerLimit!");
  }
  public void decrement()
  {
  System.out.println("Class value :"+read_value());
  System.out.println("Dec value :"+counter.read_value());
  if(counter.read_value()<=0)
  {
   System.out.println(counter.read_value());
   System.out.println("Too Low");
  }
  else
  {
   System.out.println("decrement me here in The Counter with class LowerLimit!");
   counter.decrement();
  }
  }
  /*public void increment()
  {
  counter.increment();
  }
  public int read_value()
  {
  return counter.read_value();
  }*/
  }

  class CounterFactory
  {
  public static Counter createCounter(int value,int op)
  {
  switch(op)
  {
   case 1:
   {
    return new Counter(value);
   }
   case 2:
   {
    return new UpperLimit(new Counter(value));
   }
   case 3:
   {
    return new LowerLimit(new Counter(value));
   }
   default:
   {
    return new UpperLimit(new LowerLimit(new Counter(value)));
   }
  }
  }

  }
  class Console
  {
  private static BufferedReader read=new BufferedReader(new InputStreamReader(System.in));

  public static int readInt(String index){
  System.out.println(index);
  try{
   return Integer.parseInt(read.readLine());
  }
  catch(Exception e){
   return 0;
  }
  }
  }

  public class Q1s{
  public static void main(String[] args){
  System.out.println("Counter Type:");
  System.out.println("1: Normal");
  System.out.println("2: Upper Limit");
  System.out.println("3: Lower Limit");
  System.out.println("4: Upper & Lower Limit");
  int option=Console.readInt("Enter Choice:");
  Counter c = CounterFactory.createCounter(6,option);
  int choice=1;
  while(choice!=4){
   System.out.println("1: Increment");
   System.out.println("2: Decrement");
   System.out.println("3: Read Value");
   System.out.println("4: Exit");
   choice=Console.readInt("Enter Choice:");
   switch(choice){
    case 1: c.increment(); break;
    case 2: c.decrement(); break;
    case 3: int v=c.read_value();
    System.out.println("Value="+v);break;
   }
  }
  }
  }

  按如下步驟運行出現明顯問題:

  1:選3,"Lower Limit",

  2:選3,"Read Value" 獲得的值是 6
  
  3:選1,"Increment"(此后value值應為 7)

  4:選3,"Read Value" 獲得的值是 7(正確)

  5:選2,"Decrement"(此后的value值應為 6)

  6:選3,"Read Value" 獲得的值為 7 (問題出現了)

  考察 Upper Limit 時同樣出現該問題

  三:追究

  從輸出的追蹤語句可以看出在class LowerLimit的decrement方法的開始兩輸出語句具有明顯的指導意義而其中一方法是調用的來自父類的read_value()而另一個為聚合對象的read_value()。在上面步驟的第六步兩句分別輸出

  Class value :7
  Dec value :6

  可見,有兩份value的存在。問題是兩份如何產生?

  繼續觀察,工廠在開關語句選中case 3時調用的是

  return new LowerLimit(new Counter(value));

  其中新建一匿名對象為參數,繼續追蹤該過程,發現在class Decorator 中該匿名對象被Decorator的屬性指向,而在指向之前,Decorator還把該匿名對象傳給其父類,而父類取得該對象后僅僅是取出該對象中value的拷貝,由此有兩份value存在:

  1.在Decorator自身中(父類的value)

  2.也在Decorator自身中(成員變量Counter的value屬性)!

  問題漸漸明朗,再次觀察class LowerLimit,它僅僅實現了decrement()方法,也就是說,對LowerLimit調用read_value()與increment()時,其全部追溯到其父類中執行,而被作用的值value為第一類型值。對LowerLimit調用decrement()方法時,該方法是用其成員變量Counter的read_value()來執行的。此時被作用的值為第二類型值.所以會出現value值不同步的現象。

  四:解決

  很明顯,解決方法在于僅使用其中一份value值,當然,Decorator本身的目的便在于避免使用繼承,所以應當覆蓋原有的方法,用成員變量的方法實現內部實現。也就是將代碼中的注釋去掉.

  五:小結

  父類獲得了只是值的拷貝 而本身的聚合對象獲得了(參數的)全部的引用否則 如果有方法沒有覆蓋原來的 則該方法將沿用父類的 在拷貝的值(value)上操作而被覆蓋了的方法的將對本身聚合的對象中的值(value)進行操作 于是兩value值產生分歧。

  從Decorator模式本身的用意可知:在已有的類基礎上的動態功能的添加(不是用繼承來實現,以防太深,難以控制)所以,構造函數的參數應當也必須作為"已有的類基礎"來對待,也就是說,自身的聚合對象必須是
  該參數的引用,所有的方法也必須重造,否則將落入繼承的陷阱。


主站蜘蛛池模板: 色天使在线观看 | 日韩专区第一页 | 天堂资源8中文最新版在线 天堂中文字幕在线 | 日本一区免费在线 | 日韩视频在线观看免费 | 欧美行性性性o00x | 日本最新免费二区三区 | 日本在线一本 | 婷婷综合丁香 | 色播成人网 | 在线观看国产日韩 | 日本大胆欧美人术艺术 | 亚洲精品在线第一页 | 亚洲 欧美 精品 | 色综合欧美色综合七久久 | 午夜成人免费影院 | 一级做a爰片久久毛片看看 一级做a爰片久久毛片16 | 日韩a在线观看 | 四虎永久免费观看 | 青娱乐中文字幕 | 亚洲精品亚洲人成在线 | 性亚洲 | 色综合色综合 | 欧美性猛交xxxx乱大交be | 先锋在线资源站 | 天天噜夜夜操 | 午夜欧美视频 | 色综合一区 | 在线视频欧美亚洲 | 午夜毛片视频 | 亚洲成a人 | 特黄一级真人毛片 | 色视频在线观看免费 | 亚洲国产欧美在线成人aaaa | 日韩黄色片视频 | 青草国产精品久久久久久久久 | 中文字幕免费高清视频 | 中日韩免费视频 | 天天插天天操天天射 | 日本免费人做人一区在线观看 | 日本大片网 |