学习笔记:设计模式-装饰器设计模式(JAVA)
概念
- 裝飾器設計模式,也叫包裝設計模式,他是作為現(xiàn)有類的一個包裝,允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。
- 給對象添加功能,一般兩種方式,繼承或者組合,將一個類的對象嵌入到另一個對象中,由另一個對象來決定是否調(diào)用嵌入對象的行為來增強功能,這個就是裝飾器模式,比繼承更加靈活。
- 裝飾器設計模式中幾個角色
- 抽象組件(Component):定義裝飾方法的規(guī)范
- 被裝飾者(ConcreteComponent):Component的具體實現(xiàn),也就是具體的裝飾對象
- 裝飾者組件(Decorator):定義具體裝飾者的行為規(guī)范,和Component角色有相同的接口,持有組件(Component)對象的實例引用
- 具體裝飾物(ConcreteDecorator):負責給構(gòu)建對象裝飾附加功能
應用場景
????????對于裝飾器設計模式上面概念介紹看起來屬實是比較抽象的,舉兩個通俗易解的例子。
????????場景一:小明由于預算有限,但是也想買一臺能吃雞的電腦,所以小明決定自己去當?shù)財?shù)碼一條街自己買配件組裝一臺價格低廉能吃雞的臺式機。主板、CPU、顯卡、電源、硬盤內(nèi)存等等,只要購買全所有配件,小明便可以自己組裝一臺自己心儀的電腦。
? ? ? ? 電腦即抽象組件;ROG電腦、聯(lián)想電腦或戴爾電腦就是被裝飾者;CPU和顯卡即裝飾者組件,i5 12100、RTX2060這就是具體裝飾物,如下圖概述了幾個角色間的關(guān)系。(圖其實不太準確,被裝飾組件應該拆分成CPU、GPU、主版本等,具體裝飾就是具體型號的物品了)
? ? ? ? 場景二:最近比較熱門的割草游戲《brotato》又名《土豆兄弟》,如果玩過土豆兄弟這款游戲的或者類似割草游戲的應該比較清楚,其中道具部分我們也可以通過裝飾器設計模式去完成游戲這部分內(nèi)容。英雄即為抽象組件;具體英雄如多面手、獨臂、幸運星等是被裝飾者;道具是抽象組件;具體道具如翅膀、存錢罐、手銬就是具體裝飾。玩家在游玩過程拾取和購買各種道具,通過這些不同道具給角色增加各種屬性加成,使得玩家能夠支撐20波,最終消滅BOSS。
JAVA代碼實現(xiàn)
就上面買電腦的場景,我們來用Java去實現(xiàn)買配件組裝電腦的過程
抽象組件電腦
Computer.java public interface Computer {/*** 名稱** @return*/String getDesc();/*** 價格** @return*/int getPrice();}被裝飾者
這里列舉三個(其實這里面機箱應該提取出來作為裝飾組件的,這里偷懶了,直接和品牌掛鉤了)
DiyComputer.java /*** DIY臺式機*/ public class DiyComputer implements Computer {@Overridepublic String getDesc() {return "DIY臺式機";}@Overridepublic int getPrice() {// DIY機箱便宜些,默認為300return 300;} } LegionComputer.java /*** 聯(lián)想拯救者臺式機*/ public class LegionComputer implements Computer {@Overridepublic String getDesc() {return "DIY臺式機";}@Overridepublic int getPrice() {// 拯救者機箱500return 500;} } RogComputer.java /*** 玩家國度臺式機*/ public class RogComputer implements Computer {@Overridepublic String getDesc() {return "ROG臺式機";}@Overridepublic int getPrice() {// ROG機箱1500return 1500;} }被裝飾組件
ComputerComponent.java /*** 電腦配件基類*/ public class ComputerComponent implements Computer {protected Computer computer;protected String desc = "";protected int price = 0;public ComputerComponent(Computer computer, CompunentEnum compunentEnum) {this.computer = computer;this.desc = compunentEnum.getType();this.price = compunentEnum.getPrice();}@Overridepublic String getDesc() {return computer.getDesc() + "\r\n" + desc;}@Overridepublic int getPrice() {return computer.getPrice() + price;}}具體裝飾
下面是臺式機電腦的6個配件,組裝成一個臺式機遠不是下面這些,這里只是把比較核心和大家比較關(guān)注的拿出來了。????????
其他
這里方便組件的創(chuàng)建,把常見的配件型號和價格做成一個枚舉。
枚舉基類:CompunentEnum.java public interface CompunentEnum {String getType();int getPrice();} CpuEnum.java public enum CpuEnum implements CompunentEnum {CPU_I3_12100("i3 12100", 1100),CPU_I5_12600("i5 12600", 1900),CPU_I7_12700("i7 12700", 2600),CPU_I9_12900("i9 12900", 3900);private String type;private int price;CpuEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} } DiskEnum.java public enum DiskEnum implements CompunentEnum {WD_SATA_1T("西部數(shù)據(jù)(WD)藍盤 1TB", 300),WD_SATA_2T("西部數(shù)據(jù)(WD)藍盤 2TB", 380),WD_SATA_2T_NEW("西部數(shù)據(jù)(WD)藍盤 2TB 新", 400),WD_SATA_3T("西部數(shù)據(jù)(WD)藍盤 3TB", 430),WD_SATA_4T("西部數(shù)據(jù)(WD)藍盤 4TB", 580),WD_SATA_6T("西部數(shù)據(jù)(WD)藍盤 6TB", 960),WD_SATA_8T("西部數(shù)據(jù)(WD)藍盤 6TB", 1310),WD_SSD_240G("西部數(shù)據(jù)(WD) Green SSD固態(tài)硬盤 240G", 170),WD_SSD_480G("西部數(shù)據(jù)(WD) Green SSD固態(tài)硬盤 480G", 270),WD_SSD_1T("西部數(shù)據(jù)(WD) Green SSD固態(tài)硬盤 1T", 530),WD_SSD_2T("西部數(shù)據(jù)(WD) Green SSD固態(tài)硬盤 2T", 1100),ST_SATA_1T("希捷(Seagate)1TB", 300),ST_SATA_2T("希捷(Seagate)2TB", 380),ST_SATA_4T("希捷(Seagate)4TB", 550),ST_SATA_6T("希捷(Seagate)6TB", 820),ST_SATA_8T("希捷(Seagate)8TB", 1200),ST_SSD_500G("希捷(SEAGATE) SSD固態(tài)硬盤 500G", 300),ST_SSD_1T("希捷(SEAGATE) SSD固態(tài)硬盤 1T", 550),ST_SSD_2T("希捷(SEAGATE) SSD固態(tài)硬盤 2T", 1130),SAMSUNG_SSD_870_QVO_1T("三星(SAMSUNG)2TB SSD固態(tài)硬盤 SATA3.0接口 870 QVO 1T", 600),SAMSUNG_SSD_870_QVO_2T("三星(SAMSUNG)2TB SSD固態(tài)硬盤 SATA3.0接口 870 QVO 2T", 1500),SAMSUNG_SSD_870_QVO_4T("三星(SAMSUNG)2TB SSD固態(tài)硬盤 SATA3.0接口 870 QVO 4T", 3000),SAMSUNG_SSD_870_QVO_8T("三星(SAMSUNG)2TB SSD固態(tài)硬盤 SATA3.0接口 870 QVO 8T", 5800),SAMSUNG_SSD_870_EVO_256G("三星(SAMSUNG)250GB SSD固態(tài)硬盤 SATA3.0接口 870 EVO 256G", 240),SAMSUNG_SSD_870_EVO_512G("三星(SAMSUNG)250GB SSD固態(tài)硬盤 SATA3.0接口 870 EVO 512G", 400),SAMSUNG_SSD_870_EVO_1T("三星(SAMSUNG)250GB SSD固態(tài)硬盤 SATA3.0接口 870 EVO 1T", 800),SAMSUNG_SSD_870_EVO_2T("三星(SAMSUNG)250GB SSD固態(tài)硬盤 SATA3.0接口 870 EVO 2T", 2000),SAMSUNG_SSD_870_EVO_4T("三星(SAMSUNG)250GB SSD固態(tài)硬盤 SATA3.0接口 870 EVO 4T", 3700),SAMSUNG_SSD_970_EVO_PLUS_256G("三星(SAMSUNG)250GB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議) 970 EVO Plus 256G", 350),SAMSUNG_SSD_970_EVO_PLUS_512G("三星(SAMSUNG)250GB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議) 970 EVO Plus 512G", 470),SAMSUNG_SSD_970_EVO_PLUS_1T("三星(SAMSUNG)250GB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議) 970 EVO Plus 1T", 900),SAMSUNG_SSD_970_EVO_PLUS_2T("三星(SAMSUNG)250GB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議) 970 EVO Plus 2T", 1700),SAMSUNG_SSD_980_PRO_500G("三星(SAMSUNG)1TB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議PCIe 4.0 x4) 980 PRO 500G", 600),SAMSUNG_SSD_980_PRO_1T("三星(SAMSUNG)1TB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議PCIe 4.0 x4) 980 PRO 1T", 1000),SAMSUNG_SSD_980_PRO_2T("三星(SAMSUNG)1TB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議PCIe 4.0 x4) 980 PRO 2T", 2200),SAMSUNG_SSD_980_PRO_HEATSINT_1T("三星(SAMSUNG)1TB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議PCIe 4.0 x4) 980 PRO With Heatsink(散熱片版) 1T", 1100),SAMSUNG_SSD_980_PRO_HEATSINT_2T("三星(SAMSUNG)1TB SSD固態(tài)硬盤 M.2接口(NVMe協(xié)議PCIe 4.0 x4) 980 PRO With Heatsink(散熱片版) 2T", 2300);private String type;private int price;DiskEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} } GpuEnum.java public enum GpuEnum implements CompunentEnum {COLORFUL_GEFORCE_RTX_2060("七彩虹(Colorful) RTX 2060", 1700),COLORFUL_GEFORCE_RTX_3060_DUO("七彩虹(Colorful)戰(zhàn)斧 GeForce RTX 3060 DUO 8GB", 2400),COLORFUL_GEFORCE_RTX_3060_TI("七彩虹(Colorful)iGame GeForce RTX 3060 Ti Ultra W OC G6X V2", 3600),COLORFUL_GEFORCE_RTX_3070_TI("七彩虹(Colorful)iGame GeForce RTX 3070 Ti Ultra W OC 8G", 4500),COLORFUL_GEFORCE_RTX_4090_TI("七彩虹(Colorful)水神iGame GeForce RTX 4090 Neptune OC 24G", 15000),ASUS_RX_6500XT("華碩 ASUS DUAL-RX6500XT-O4G", 1400),ASUS_GTX_1660S("華碩 (ASUS)TUF-GeForce GTX 1660S-O6G-GAMING", 1700),ASUS_RTX_2060("華碩 ASUS DUAL GeForce RTX 2060-O6G-EVO", 2300),ASUS_RTX_3060("華碩 ASUS TUF GeForce RTX 3060-O12G-V2-GAMING", 3200),ASUS_RTX_3070_TI("華碩 ASUS TUF GeForce RTX 3070 Ti-O8G-GAMING", 5300),ASUS_RTX_3080("華碩 ASUS TUF GeForce RTX 3080-O10G-V2-GAMING", 6300),ASUS_RTX_4090("華碩 (ASUS) TUF-GeForce RTX 4090-O24G-GAMING", 14000),MSI_RTX_1660S("微星(MSI)魔龍 GeForce GTX 1660 SUPER", 2000),MSI_RTX_2060("微星(MSI)萬圖師 GeForce RTX 2060 VENTUS GP OC", 2000),MSI_RTX_3050("微星(MSI)萬圖師 GeForce RTX 3050 VENTUS 2X 8G OC", 2100),MSI_RTX_3060("微星(MSI)萬圖師 GeForce RTX 3060 VENTUS 2X 12G OC", 3000),MSI_RTX_3060_TI("微星(MSI)萬圖師 GeForce RTX 3060 Ti VENTUS 2X 8G OCV1 LHR", 3500),MSI_RTX_3090_TI("微星(MSI)超龍 GeForce RTX 3090 Ti SUPRIM X 24G", 13000),MSI_RTX_4090("微星(MSI)魔龍 GeForce RTX 4090 GAMING X TRIO 24G", 13000);private String type;private int price;GpuEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} } MainBoardEnum.java public enum MainBoardEnum implements CompunentEnum {ASUS_TUF_GAMING_B450M_PLUS("華碩TUF GAMING B450M-PLUS WIFI", 540),ASUS_TUF_GAMING_B550M_PLUS("華碩TUF GAMING B550M-PLUS WIFI", 850),ASUS_TUF_GAMING_B650M_PLUS("華碩TUF GAMING B650M-PLUS WIFI", 1500),ASUS_TUF_GAMING_B650_PLUS("華碩TUF GAMING B650-PLUS WIFI", 1900),ASUS_TUF_GAMING_X670E_PLUS("華碩(ASUS)TUF GAMING X670E-PLUS", 2600),ASUS_PRO_ART_X670E("華碩(ASUS)ProArt X670E-CREATOR WIFI", 5000),ASUS_TUF_GAMING_ZX670P_PLUS("華碩(ASUS)TUF GAMING ZX670-P", 2300),ASUS_PRIME_X670E_PRO("華碩(ASUS)PRIME X670E-PRO", 2600),COLORFUL_X570M_FROZEN("七彩虹(Colorful)CVN X570M GAMING FROZEN V14", 800),COLORFUL_X570M_PRO("七彩虹(Colorful)CVN X570M GAMING PRO V14", 750),COLORFUL_B550_FROZEN("七彩虹(Colorful)CVN B550M GAMING FROZEN V14", 630),COLORFUL_B550_PRO("七彩虹(Colorful)CVN B550M GAMING FROZEN V14", 650),COLORFUL_A520M_PRO("七彩虹(Colorful)A520M-K PRO V14", 400),GIGABYTE_B660_MASTER("技嘉(GIGABYTE)超級雕B660 AORUS MASTER", 1800),GIGABYTE_B660_PRO("技嘉(GIGABYTE)超級雕B660 AORUS MASTER", 1250);private String type;private int price;MainBoardEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} } PowerEnum.java public enum PowerEnum implements CompunentEnum {BUBALUS_200W("大水牛(BUBALUS)額定200W", 90),BUBALUS_250W("大水牛(BUBALUS)額定250W", 100),BUBALUS_300W("大水牛(BUBALUS)額定300W", 115),BUBALUS_400W("大水牛(BUBALUS)額定400W", 145),BUBALUS_500W("大水牛(BUBALUS)額定500W", 170),BUBALUS_600W("大水牛(BUBALUS)額定600W", 210),BUBALUS_650W("大水牛(BUBALUS)額定650W", 230),GIGABYTE_450W("技嘉(GIGABYTE)臺式電腦主機電源 450W", 290),GIGABYTE_550W("技嘉(GIGABYTE)臺式電腦主機電源 550W", 350),GIGABYTE_650W("技嘉(GIGABYTE)臺式電腦主機電源 650W", 470),GIGABYTE_750W("技嘉(GIGABYTE)臺式電腦主機電源 750W", 700),GIGABYTE_850W("技嘉(GIGABYTE)臺式電腦主機電源 850W", 800),GREATEWALL_HOPE_350W("長城(GreatWall)額定350W HOPE-4500DS電腦電源", 190),GREATEWALL_HOPE_400W("長城(GreatWall)額定350W HOPE-5000DS電腦電源", 200),GREATEWALL_HOPE_450W("長城(GreatWall)額定350W HOPE-5500DS電腦電源", 210),GREATEWALL_HOPE_500W("長城(GreatWall)額定350W HOPE-6000DS電腦電源", 250),GREATEWALL_HOPE_600W("長城(GreatWall)額定350W HOPE-7000DS電腦電源", 310),GREATEWALL_HOPE_700W("長城(GreatWall)額定350W HOPE-8000DS電腦電源", 370),USCORSAIR_RM750_750W("美商海盜船 (USCORSAIR) RM750 750W電源", 900),USCORSAIR_RM850_850W("美商海盜船 (USCORSAIR) RM850 850W電源", 1000),USCORSAIR_RM650X_650W("美商海盜船 (USCORSAIR) RM650x 650W電源", 850),USCORSAIR_RM750X_750W("美商海盜船 (USCORSAIR) RM750x 750W電源", 850),USCORSAIR_RM850X_850W("美商海盜船 (USCORSAIR) RM850x 850W電源", 950),USCORSAIR_RM1000X_1000W("美商海盜船 (USCORSAIR) RM850x 850W電源", 1000),USCORSAIR_HX1000_1000W("美商海盜船 (USCORSAIR) HX1000 1000W電源", 1600),USCORSAIR_HX1000I_1000W("美商海盜船 (USCORSAIR) HX1000i 1000W電源", 1800),USCORSAIR_HX1200_1200W("美商海盜船 (USCORSAIR) HX1200 1200W電源", 3450),USCORSAIR_HX1500I_1500W("美商海盜船 (USCORSAIR) HX1500i 1600W電源", 2800),USCORSAIR_AX1500I_1600W("美商海盜船 (USCORSAIR) AX1600i 1600W電源", 3450),CPU_I9_12900("i9 12900", 3900);private String type;private int price;PowerEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} } RamEnum.java public enum RamEnum implements CompunentEnum {KINGSTON_DDR4_8G("金士頓 (Kingston) FURY 8GB DDR4 3200 8G", 220),KINGSTON_DDR4_16G("金士頓 (Kingston) FURY 8GB DDR4 3200 16G", 320),KINGSTON_DDR4_32G("金士頓 (Kingston) FURY 8GB DDR4 3200 32G", 800),ADATA_DDR4_8G("威剛(ADATA) XPG 龍耀 D50 吹雪限定款 DDR4 3600 RGB 8G", 350),ADATA_DDR4_16G("威剛(ADATA) XPG 龍耀 D50 吹雪限定款 DDR4 3600 RGB 16G", 600),USCORSAIR_DDR_3200_8G("美商海盜船(USCORSAIR) 8GB DDR4 3200 8G", 210),USCORSAIR_DDR_3200_16G("美商海盜船(USCORSAIR) 16GB DDR4 3200 16G", 400),USCORSAIR_DDR_3200_32G("美商海盜船(USCORSAIR) 32GB DDR4 3200 32G", 790),USCORSAIR_DDR_3600_8G("美商海盜船(USCORSAIR) 8GB DDR4 3600 8G", 290),USCORSAIR_DDR_3600_16G("美商海盜船(USCORSAIR) 16GB DDR4 3600 16G", 520),USCORSAIR_DDR_3600_32G("美商海盜船(USCORSAIR) 32GB DDR4 3600 32G", 1320);private String type;private int price;RamEnum(String type, int price) {this.type = type;this.price = price;}@Overridepublic String getType() {return this.type;}@Overridepublic int getPrice() {return this.price;} }如何使用
? ? ? ? 到這里整個電腦組裝基于裝飾器設計模式的代碼已經(jīng)寫完,為了方便大家看清,這里簡單畫個關(guān)系圖,幫助大家去理解。
下面看如果使用
ComputerTest.java
public class ComputerTest {public static void main(String[] args) {Computer computer = new DiyComputer();// 七彩虹七彩虹主板computer = new MainBoardComponent(computer, MainBoardEnum.COLORFUL_A520M_PRO);// 技嘉450W電源computer = new PowerComponent(computer, PowerEnum.GIGABYTE_450W);// cpu i5 12代computer = new CpuComponent(computer, CpuEnum.CPU_I5_12600);// 顯卡1660computer = new GpuComponent(computer, GpuEnum.ASUS_GTX_1660S);// 一個256BG的SSD,一個2T的機械computer = new DiskComponent(computer, DiskEnum.ST_SATA_2T);computer = new DiskComponent(computer, DiskEnum.SAMSUNG_SSD_870_EVO_256G);// 四個8Gcomputer = new RamComponent(computer, RamEnum.KINGSTON_DDR4_8G);computer = new RamComponent(computer, RamEnum.KINGSTON_DDR4_8G);computer = new RamComponent(computer, RamEnum.KINGSTON_DDR4_8G);computer = new RamComponent(computer, RamEnum.KINGSTON_DDR4_8G);System.out.println(computer.getDesc());System.out.println("價格: " + computer.getPrice());}}下運行結(jié)果(小明同學花了6000塊組裝了一臺可以吃雞的電腦了)
同事小王發(fā)了年終,想給自己配一臺高配臺式機玩使命召喚19,大家覺得小王同學配的這臺電腦怎么樣
public class ComputerTest2 {public static void main(String[] args) {Computer computer = new RogComputer();// 華碩主板computer = new MainBoardComponent(computer, MainBoardEnum.ASUS_PRO_ART_X670E);// 海盜船1600W帶能源computer = new PowerComponent(computer, PowerEnum.USCORSAIR_AX1500I_1600W);// cpu i9 12代computer = new CpuComponent(computer, CpuEnum.CPU_I9_12900);// 顯卡4090computer = new GpuComponent(computer, GpuEnum.ASUS_RTX_4090);// 兩個三星SSD 2Tcomputer = new DiskComponent(computer, DiskEnum.SAMSUNG_SSD_980_PRO_HEATSINT_2T);computer = new DiskComponent(computer, DiskEnum.SAMSUNG_SSD_980_PRO_HEATSINT_2T);// 四個海盜船32G內(nèi)存computer = new RamComponent(computer, RamEnum.USCORSAIR_DDR_3600_32G);computer = new RamComponent(computer, RamEnum.USCORSAIR_DDR_3600_32G);computer = new RamComponent(computer, RamEnum.USCORSAIR_DDR_3600_32G);computer = new RamComponent(computer, RamEnum.USCORSAIR_DDR_3600_32G);System.out.println(computer.getDesc());System.out.println("價格: " + computer.getPrice());}}?
最后,有不對的地方歡迎大家指正,時間比較倉促,例子還有很多缺陷需要改正的地方~
第一個:ComputerTest中小明如果沒有買電源,其實這個時候是無法組裝電腦,由于電腦的特殊性,并不是完全適合修飾器設計模式的,還需要我們加上完備性校驗,哪些配件是必須品哪些是可選配件,哪些配件可以購買多個,還有主板支不支持等等,這些都可以去完善。
第二個:針對上面問題可以結(jié)合工廠設計模式,所以對于電腦小白不由他自己去選購配件,而是直接提供訴求,由電腦工廠去直接去配置出一臺完整的電腦給消費者。
總結(jié)
以上是生活随笔為你收集整理的学习笔记:设计模式-装饰器设计模式(JAVA)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: flexslider插件使用体会
- 下一篇: asp.net ajax控件工具集 Au