日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

装饰模式——初学JAVA设计模式

發布時間:2023/12/29 asp.net 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 装饰模式——初学JAVA设计模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、基本概念
    • 模式角色
  • 二、簡單實例
    • 實例一、變形金剛
      • 類圖
      • 代碼實現
      • 結果截圖
    • 實例二、喜羊羊與灰太狼
      • 類圖
      • 方式一:半透明模式
        • 代碼實現
        • 結果截圖
      • 方式二:半透明模式+透明模式
        • 代碼實現
        • 結果截圖
  • 三、透明模式和半透明模式的區別
      • 辨析
      • 透明模式
      • 半透明模式
  • 四、小結
    • 優缺點
    • 適用場景

一、基本概念

裝飾模式是一種用于替代繼承的技術,它通過一種無須定義子類的方式來給對象動態增加職責,使用對象之間的關聯關系取代類之間的繼承關系。

裝飾模式(Decorator)定義:動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更靈活。

模式角色

  • Component(抽象構件類):定義了對象的接口,可以給這些對象動態增加職責(方法),是具體構建和抽象裝飾類的共同父類,聲明了具體構件中需要實現的方法。

  • ConcreteComponent(具體構件類):定義了具體的構建對象,實現了在抽象構建中聲明的方法,裝飾器可以給他增加額外的方法。

  • Decorator(抽象裝飾類):是抽象構建類的子類,用于具體構件增加職責。

  • ConcreteDecorator(具體裝飾類):是抽象裝飾類的子類,負責增添加新的職責。

二、簡單實例

實例一、變形金剛

類圖

代碼實現

  • 抽象構件類Transform(變形金剛)
package com.transform;public interface Transform {public void move(); //移動方法 }

接口中定義move()方法,具體構件類必須實現此方法。

  • 具體構件類Car(汽車類)
package com.transform; /*** @Description:具體構件類* 注意這里的Car設置為final類型* 意味著不能通過繼承拓展其功能,但是可以通過關聯關系來拓展功能*/ public final class Car implements Transform {public Car() {System.out.println("變形金剛是一輛車!");}@Overridepublic void move() {System.out.println("在陸地上移動");} }
  • 抽象裝飾類Changer(變化類)
package com.transform;/*** @Description:具體裝飾類Changer* 具體裝飾類是裝飾模式的核心* 實現了move方法,保證原有方法不會丟失,又可以添加新的功能*/ public class Changer implements Transform{private Transform transform;//構造方法注入public Changer(Transform transform) {this.transform = transform;}@Overridepublic void move() {transform.move();} }
  • 具體裝飾類Robot(機器人類)
package com.transform; /*** @Description:具體裝飾類*/ public class Robot extends Changer {//用構造方法繼承了父類定義的方法,還可以增加新的職能public Robot(Transform transform) {super(transform);System.out.println("變成機器人");}public void say(){System.out.println("你tm說話啊!");} }
  • 具體裝飾類Airplane(飛機類)
package com.transform; /*** @Description:具體裝飾類*/ public class Robot extends Changer {//用構造方法繼承了父類定義的方法,還可以增加新的職能public Robot(Transform transform) {super(transform);System.out.println("變成機器人");}public void say(){System.out.println("你tm說話啊!");} }
  • 客戶端Client
package com.transform; /*** @Description:*/ public class Client {public static void main(String[] args) {//創建carmaro對象Transform camaro;camaro = new Car();camaro.move();System.out.println("-------------------------");Robot bumblebee = new Robot(camaro);bumblebee.move();bumblebee.say();} }

結果截圖

實例二、喜羊羊與灰太狼

題目: “喜羊羊逃命”游戲:喜羊羊被灰太狼追,喜羊羊最多5條命,灰太狼每咬到喜羊羊一次,喜羊羊就要少一條命。在逃的過程中喜羊羊可以吃到三種蘋果,吃“紅蘋果”可以給喜羊羊加上保護罩,吃“綠蘋果”可以加快喜羊羊奔跑速度,吃“黃蘋果”可以使喜羊羊趟著水跑。應用裝飾模式,用JAVA控制臺應用程序實現該設計。繪制該模式的UML圖。
提示:這個例子如果用類的繼承來實現的話那可就麻煩了,你需要為喜羊羊派生321=6個子類(有保護罩的喜羊羊,奔跑速度加快的喜羊羊,會趟水的喜羊羊,既有保護罩又會趟水的喜羊羊,奔跑速度快且會趟水的喜羊羊,有保護罩且奔跑速度快的喜羊羊,有保護罩、奔跑速度快且會趟水的喜羊羊),如果使用裝飾模式的那就不用派生諸多子類了,當喜羊羊每吃到一個蘋果,我們就用裝飾模式給喜羊羊加一個動態增加一個新功能即可。

類圖

方式一:半透明模式

實質方式一是以構造方法注入方式實現,方式二通過調用子類新添加的方法實現。

代碼實現

  • 抽象構件類Appearance
package sheep; /*** @Description:抽象構建類*/ abstract class Appearance {public int lives;public abstract void display(); }
  • 具體構件類Sheep
package sheep; /*** @Description:具體構建類*/ public final class Sheep extends Appearance {public String name;public Sheep(String name) {this.name = name;}public void setlives(int lives) {this.lives = lives;}@Overridepublic void display() {System.out.println(name+"的狀態:");} }
  • 抽象裝飾類Decorator
package sheep; /*** @Description:抽象裝飾類*/ public class Decorator extends Appearance {protected Appearance appearance;//裝飾方法public void Decorate(Appearance appearance){this.appearance = appearance;this.lives = appearance.lives;}@Overridepublic void display() {if (appearance!=null){ //確保注入成功appearance.display();}} }
  • 具體裝飾類:GreenApple
package sheep; /*** @Description:具體裝飾類*/ public class GreenApple extends Decorator {@Overridepublic void display() {appearance.lives = lives; //更新組件的lives屬性//注意這兩句不能上下調轉super.display();System.out.println("吃了綠蘋果,具有加速技能,生命值為"+appearance.lives);} }
  • 具體裝飾類RedApple
package sheep; /*** @Description:具體裝飾類*/ public class RedApple extends Decorator {@Overridepublic void display() {this.appearance.lives = lives;//更新組件的lives屬性//注意這兩句不能上下調轉super.display();System.out.println("吃了紅蘋果,具有保護罩技能,生命值為"+appearance.lives);} }

還有一個具體裝飾類,YellowApple代碼省略…

  • 具體裝飾類WolfAtack
package sheep; /*** @Description:具體構架類:狼咬羊類*/ public class WolfAtack extends Decorator {@Overridepublic void display() {super.display();//注意這兩句不能上下調轉this.appearance.lives = appearance.lives - 1;System.out.println();System.out.println("----------------------------------");System.out.println("被狼咬了一口,生命值-1,生命值為"+appearance.lives);System.out.println("----------------------------------");System.out.println();} }
  • 客戶端Client
package sheep; public class Client {public static void main(String[] args) {//半透明模式:可以調用其他方法Sheep sheep = new Sheep("喜羊羊");sheep.setlives(5);//設置初始為5條命//半透明模式:可以調用其他方法Decorator redApple,greenApple,yellowApple;//聲明一只狼Decorator wolf = new WolfAtack();//羊吃了紅蘋果redApple = new RedApple();redApple.Decorate(sheep);//狼咬了羊wolf.Decorate(redApple);wolf.display();//羊又吃了綠蘋果greenApple = new GreenApple();greenApple.Decorate(redApple);//狼咬了羊wolf.Decorate(greenApple);wolf.display();yellowApple = new YellowApple();yellowApple.Decorate(greenApple);//現在羊的狀態yellowApple.display();} }

結果截圖

方式二:半透明模式+透明模式

代碼實現

  • 抽象構件類Appearance
package sheet; /*** @Description:抽象構件類*/ abstract class Appearance {public int lives;public abstract void display(); }
  • 具體構建類
package sheet; /*** @Description:具體構件類*/ public final class Sheep extends Appearance {public String name;public Sheep(String name) {this.name = name;}public void setlives(int lives) {this.lives = lives;}@Overridepublic void display() {System.out.println(name+"的狀態:");} }
  • 抽象裝飾類
package sheet; /*** @Description:抽象裝飾類*/ public class Decorator extends Appearance {protected Appearance appearance;public Decorator(Appearance appearance) {this.appearance = appearance;this.lives = appearance.lives;}@Overridepublic void display() {appearance.display();} }
  • 具體裝飾類:只寫GreenApple類省略了YellowApple和RedApplle代碼
package sheet;/*** @author:xiaofa* @date2020/5/111:18* @Description:具體裝飾類*/ public class GreenApple extends Decorator {public GreenApple(Appearance appearance) {super(appearance);}@Overridepublic void display() {this.appearance.lives = lives;//注意這兩句不能上下調轉super.display();System.out.println("吃了綠蘋果,具有加速技能,生命值為"+appearance.lives);} }
  • 具體實現類WolfAtack
package sheet; public class WolfAtack extends Decorator {public WolfAtack(Appearance appearance) {super(appearance);}@Overridepublic void display() {super.display();appearance.lives = appearance.lives-1;this.lives = appearance.lives;System.out.println();System.out.println("----------------------------------");System.out.println("被狼咬了一口,生命值-1,生命值為"+appearance.lives);System.out.println("----------------------------------");System.out.println();} }
  • 客戶端Client
package sheet;public class Client {public static void main(String[] args) {//半透明模式:可以調用其他方法Sheep sheep = new Sheep("喜羊羊");sheep.setlives(5);//設置初始為5條命//透明模式:不能調用其他方法Appearance redApple,greenApple,yellowApple,wolfAtack;//羊吃了紅蘋果redApple = new RedApple(sheep);//狼咬了羊wolfAtack = new WolfAtack(redApple);//狼咬了羊wolfAtack.display();//羊吃了綠蘋果greenApple = new GreenApple(redApple);//狼咬了羊wolfAtack = new WolfAtack(greenApple);//狼咬了羊wolfAtack.display();//羊吃了黃蘋果yellowApple = new YellowApple(greenApple);//羊現在的狀態yellowApple.display();} }

結果截圖

三、透明模式和半透明模式的區別

辨析

注意本實例中創建和初始化喜羊羊都是調用setlives()方法

Sheep sheep = new Sheep("喜羊羊"); sheep.setlives(5);//設置初始為5條命

而不是

Appearance sheep = new Sheep("喜羊羊"); sheep.setlives(5);//設置初始為5條命 //非法

是因為Sheep是具體構件類繼承了抽象構件類Appearance的方法,如果需要調用子類Sheep新添加的setLives方法,就要用這種半透明模式定義。


另外方式一中:

//半透明模式:不能調用其他方法Decorator redApple,greenApple,yellowApple;//聲明一只狼Decorator wolf = new WolfAtack();//羊吃了紅蘋果redApple = new RedApple();redApple.Decorate(sheep);//狼咬了羊wolf.Decorate(redApple);wolf.display();

方式二中:

//透明模式:不能調用其他方法Appearance redApple,greenApple,yellowApple,wolfAtack;//羊吃了紅蘋果redApple = new RedApple(sheep);//狼咬了羊wolfAtack = new WolfAtack(redApple);

方式一是半透明模式,調用了具體裝飾類中新添加的Decorate()方法;而方式二是透明模式,不能直接調用新添加的方法,但是可以一構造方法注入的方式實現。

透明模式

使用抽象構件類型Component定義全部具體構件對象和具體裝飾對象,客戶端可以一致地使用這些對象,因此符合透明裝飾模式的要求。透明裝飾模式可以讓客戶端透明地使用裝飾之前的對象和裝飾之后的對象,無須關心它們的區別,此外,還可以對一個已裝飾過的對象進行多次裝飾,得到更為復雜、功能更為強大的對象。在實現透明裝飾模式時,要求具體裝飾類的operation()方法覆蓋抽象裝飾類的operation()方法,除了調用原有對象的operation()外還需要調用新增的addedBehavior()方法來增加新行為,

半透明模式

透明裝飾模式的設計難度較大,而且有時我們需要單獨調用新增的業務方法。為了能夠調用到新增方法,我們不得不用具體裝飾類型來定義裝飾之后的對象,而具體構件類型還是可以使用抽象構件類型來定義,這種裝飾模式即為半透明裝飾模式,也就是說,對于客戶端而言,具體構件類型無須關心,是透明的;但是具體裝飾類型必須指定,這是不透明的。

思考:為什么半透明裝飾模式不能實現對同一個對象的多次裝飾?

因為在半透明裝飾模式中,使用具體裝飾類來聲明裝飾之后的對象,具體裝飾類中新增的方法并未在抽象構件類中聲明,這樣做的優點在于裝飾后客戶端可以單獨調用在具體裝飾類中新增的業務方法,但是將導致無法調用到之前裝飾時新增的方法,只能調用到最后一次裝飾時具體裝飾類中新增加的方法,故對同一個對象實施多次裝飾沒有任何意義。

四、小結

優缺點

  • 優點

(1) 對于擴展一個對象的功能,裝飾模式比繼承更加靈活性,不會導致類的個數急劇增加。

(2) 可以通過一種動態的方式來擴展一個對象的功能,通過配置文件可以在運行時選擇不同的具體裝飾類,從而實現不同的行為。

(3) 可以對一個對象進行多次裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合,得到功能更為強大的對象。

(4) 具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類,原有類庫代碼無須改變,符合“開閉原則”。

  • 缺點

(1) 使用裝飾模式進行系統設計時將產生很多小對象,這些對象的區別在于它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,大量小對象的產生勢必會占用更多的系統資源,在一定程序上影響程序的性能。

(2) 裝飾模式提供了一種比繼承更加靈活機動的解決方案,但同時也意味著比繼承更加易于出錯,排錯也很困難,對于多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為繁瑣。

適用場景

(1) 在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。

(2) 當不能采用繼承的方式對系統進行擴展或者采用繼承不利于系統擴展和維護時可以使用裝飾模式。不能采用繼承的情況主要有兩類:第一類是系統中存在大量獨立的擴展,為支持每一種擴展或者擴展之間的組合將產生大量的子類,使得子類數目呈爆炸性增長;第二類是因為類已定義為不能被繼承(如Java語言中的final類)。

參考書籍《裝飾模式——Java設計模式劉偉第二版》

總結

以上是生活随笔為你收集整理的装饰模式——初学JAVA设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。