中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站建設(shè)外包名詞解釋在線優(yōu)化工具

網(wǎng)站建設(shè)外包名詞解釋,在線優(yōu)化工具,織夢(mèng)一鍵更新網(wǎng)站,深圳總部企業(yè)名單史上最全 結(jié)構(gòu)型模式之 代理 適配器 裝飾者 模式-CSDN博客 5.4 橋接模式 5.4.1 概述 現(xiàn)在有一個(gè)需求,需要?jiǎng)?chuàng)建不同的圖形,并且每個(gè)圖形都有可能會(huì)有不同的顏色。我們可以利用繼承的方式來(lái)設(shè)計(jì)類的關(guān)系: 我們可以發(fā)現(xiàn)有很多的類,假…

史上最全 結(jié)構(gòu)型模式之 代理 適配器 裝飾者 模式-CSDN博客

5.4 橋接模式

5.4.1 概述

現(xiàn)在有一個(gè)需求,需要創(chuàng)建不同的圖形,并且每個(gè)圖形都有可能會(huì)有不同的顏色。我們可以利用繼承的方式來(lái)設(shè)計(jì)類的關(guān)系:

我們可以發(fā)現(xiàn)有很多的類,假如我們?cè)僭黾右粋€(gè)形狀或再增加一種顏色,就需要?jiǎng)?chuàng)建更多的類。

試想,在一個(gè)有多種可能會(huì)變化的維度 系統(tǒng)中,用繼承方式會(huì)造成類爆炸,擴(kuò)展起來(lái)不靈活。每次在一個(gè)維度上新增一個(gè)具體實(shí)現(xiàn)都要增加多個(gè)子類。為了更加靈活的設(shè)計(jì)系統(tǒng),我們此時(shí)可以考慮使用橋接模式。

定義:

抽象與實(shí)現(xiàn)分離,使它們可以獨(dú)立變化。它是用組合關(guān)系代替繼承關(guān)系來(lái)實(shí)現(xiàn),從而降低了抽象和實(shí)現(xiàn)這兩個(gè)可變維度的耦合度。

5.4.2 結(jié)構(gòu)

橋接(Bridge)模式包含以下主要角色:

  • 抽象化(Abstraction)角色 :定義抽象類,并包含一個(gè) 對(duì)實(shí)現(xiàn)化對(duì)象 的引用。
  • 擴(kuò)展抽象化(Refined Abstraction)角色 :是抽象化角色的子類,實(shí)現(xiàn)父類中的業(yè)務(wù)方法,并通過(guò)組合關(guān)系調(diào)用實(shí)現(xiàn)化角色中的業(yè)務(wù)方法。
  • 實(shí)現(xiàn)化(Implementor)角色 :定義實(shí)現(xiàn)化角色的接口,供擴(kuò)展抽象化角色調(diào)用。
  • 具體實(shí)現(xiàn)化(Concrete Implementor)角色 :給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)

5.4.3 案例

【例】視頻播放器

需要開(kāi)發(fā)一個(gè)跨平臺(tái)視頻播放器,可以在不同操作系統(tǒng)平臺(tái)(如Windows、Mac、Linux等)上播放多種格式的視頻文件,常見(jiàn)的視頻格式包括RMVB、AVI、WMV等。該播放器包含了兩個(gè)維度,適合使用橋接模式。

類圖如下:

代碼如下:

//視頻文件
public interface VideoFile {void decode(String fileName);
}//avi文件
public class AVIFile implements VideoFile {public void decode(String fileName) {System.out.println("avi視頻文件:"+ fileName);}
}//rmvb文件
public class REVBBFile implements VideoFile {public void decode(String fileName) {System.out.println("rmvb文件:" + fileName);}
}//操作系統(tǒng)版本
public abstract class OperatingSystemVersion {protected VideoFile videoFile;public OperatingSystemVersion(VideoFile videoFile) {this.videoFile = videoFile;}public abstract void play(String fileName);
}//Windows版本
public class Windows extends OperatingSystem {public Windows(VideoFile videoFile) {super(videoFile);}public void play(String fileName) {videoFile.decode(fileName);}
}//mac版本
public class Mac extends OperatingSystemVersion {public Mac(VideoFile videoFile) {super(videoFile);}public void play(String fileName) {videoFile.decode(fileName);}
}//測(cè)試類
public class Client {public static void main(String[] args) {OperatingSystem os = new Windows(new AVIFile());os.play("戰(zhàn)狼3");}
}

好處:

  • 橋接模式提高了系統(tǒng)的可擴(kuò)充性,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度,都不需要修改原有系統(tǒng)。

如:如果現(xiàn)在還有一種視頻文件類型wmv,我們只需要再定義一個(gè)類實(shí)現(xiàn)VideoFile接口即可,其他類不需要發(fā)生變化。

  • 實(shí)現(xiàn)細(xì)節(jié)對(duì)客戶透明

壞處:

適配器模式容易類爆炸 , 每個(gè)維度都要?jiǎng)?chuàng)建多個(gè)類

5.4.4 使用場(chǎng)景

  • 當(dāng)一個(gè)類存在兩個(gè)獨(dú)立變化的維度,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展時(shí)。
  • 當(dāng)一個(gè)系統(tǒng)不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加時(shí)。(類爆炸)
  • 當(dāng)一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性時(shí)。避免在兩個(gè)層次之間建立靜態(tài)的繼承聯(lián)系,通過(guò)橋接模式可以使它們?cè)?/strong>抽象層建立一個(gè)關(guān)聯(lián)關(guān)系。

裝飾是小的包裹大的,橋接是大的包裹小的

5.5 外觀模式

5.5.1 概述

有些人可能炒過(guò)股票,但其實(shí)大部分人都不太懂,這種沒(méi)有足夠了解證券知識(shí)的情況下做股票是很容易虧錢(qián)的,剛開(kāi)始炒股肯定都會(huì)想,如果有個(gè)懂行的幫幫手就好,其實(shí)基金就是個(gè)好幫手,支付寶里就有許多的基金,它將投資者分散的資金集中起來(lái),交由專業(yè)的經(jīng)理人進(jìn)行管理,投資于股票、債券、外匯等領(lǐng)域,而基金投資的收益歸持有者所有,管理機(jī)構(gòu)收取一定比例的托管管理費(fèi)用。

定義:

又名門(mén)面模式,是一種通過(guò)為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口,而使這些子系統(tǒng)更加容易被訪問(wèn)的模式。該模式對(duì)外有一個(gè)統(tǒng)一接口(基金),外部應(yīng)用程序不用關(guān)心內(nèi)部子系統(tǒng)的具體的細(xì)節(jié)(投資哪些),這樣會(huì)大大降低應(yīng)用程序的復(fù)雜度,提高了程序的可維護(hù)性。

外觀(Facade)模式是“迪米特法則”的典型應(yīng)

5.5.2 結(jié)構(gòu)

外觀(Facade)模式包含以下主要角色:

  • 外觀(Facade)角色:為多個(gè)子系統(tǒng)對(duì)外提供一個(gè)共同的接口。
  • 子系統(tǒng)(Sub System)角色:實(shí)現(xiàn)系統(tǒng)的部分功能,客戶可以通過(guò)外觀角色訪問(wèn)它。

5.5.3 案例

【例】智能家電控制

小明的爺爺已經(jīng)60歲了,一個(gè)人在家生活:每次都需要打開(kāi)燈、打開(kāi)電視、打開(kāi)空調(diào);睡覺(jué)時(shí)關(guān)閉燈、關(guān)閉電視、關(guān)閉空調(diào);操作起來(lái)都比較麻煩。所以小明給爺爺買(mǎi)了智能音箱,可以通過(guò)語(yǔ)音直接控制這些智能家電的開(kāi)啟和關(guān)閉。類圖如下:

代碼如下:

//燈類
public class Light {public void on() {System.out.println("打開(kāi)了燈....");}public void off() {System.out.println("關(guān)閉了燈....");}
}//電視類
public class TV {public void on() {System.out.println("打開(kāi)了電視....");}public void off() {System.out.println("關(guān)閉了電視....");}
}//控制類
public class AirCondition {public void on() {System.out.println("打開(kāi)了空調(diào)....");}public void off() {System.out.println("關(guān)閉了空調(diào)....");}
}//智能音箱 外觀類 和用戶交互
public class SmartAppliancesFacade {//聚合三個(gè)電器private Light light;private TV tv;private AirCondition airCondition;public SmartAppliancesFacade() {light = new Light();tv = new TV();airCondition = new AirCondition();}public void say(String message) {if(message.contains("打開(kāi)")) {on();} else if(message.contains("關(guān)閉")) {off();} else {System.out.println("我還聽(tīng)不懂你說(shuō)的!!!");}}//起床后一鍵開(kāi)電器private void on() {System.out.println("起床了");light.on();tv.on();airCondition.on();}//睡覺(jué)一鍵關(guān)電器private void off() {System.out.println("睡覺(jué)了");light.off();tv.off();airCondition.off();}
}//測(cè)試類
public class Client {public static void main(String[] args) {//創(chuàng)建外觀對(duì)象SmartAppliancesFacade facade = new SmartAppliancesFacade();//客戶端直接與外觀對(duì)象進(jìn)行交互facade.say("打開(kāi)家電");facade.say("關(guān)閉家電");}
}

好處:

  • 降低了子系統(tǒng)與客戶端之間的耦合度,使得子系統(tǒng)的變化不會(huì)影響調(diào)用它的客戶類
  • 對(duì)客戶屏蔽了子系統(tǒng)組件減少了客戶處理的對(duì)象數(shù)目,并使得子系統(tǒng)使用起來(lái)更加容易。

缺點(diǎn):

  • 不符合開(kāi)閉原則,修改很麻煩

5.5.4 使用場(chǎng)景

  • 對(duì)分層結(jié)構(gòu)系統(tǒng)構(gòu)建時(shí),使用外觀模式定義子系統(tǒng)中每層的入口點(diǎn)可以簡(jiǎn)化子系統(tǒng)之間的依賴關(guān)系。
  • 當(dāng)一個(gè)復(fù)雜系統(tǒng)的子系統(tǒng)很多時(shí),外觀模式可以為系統(tǒng)設(shè)計(jì)一個(gè)簡(jiǎn)單的接口供外界訪問(wèn)。
  • 當(dāng)客戶端與多個(gè)子系統(tǒng)之間存在很大的聯(lián)系時(shí),引入外觀模式可將它們分離,從而提高子系統(tǒng)的獨(dú)立性和可移植性。

5.5.5 源碼解析(tomcat)

使用tomcat作為web容器時(shí),接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求,tomcat會(huì)將請(qǐng)求信息封裝成Servlet Request對(duì)象,如下圖①處對(duì)象。

但是大家想想ServletRequest是一個(gè)接口,它還有一個(gè)子接口HttpServletRequest,而我們知道該request對(duì)象肯定是一個(gè)HttpServletRequest對(duì)象和ServletRequest共同的子實(shí)現(xiàn)類對(duì)象,到底是哪個(gè)類的對(duì)象呢?可以通過(guò)輸出request對(duì)象,我們就會(huì)發(fā)現(xiàn)是一個(gè)名為RequestFacade的類的對(duì)象

RequestFacade類就使用了外觀模式。先看結(jié)構(gòu)圖:

為什么在此處使用外觀模式呢?

定義 RequestFacade 類,分別實(shí)現(xiàn) ServletRequest ,同時(shí)定義私有成員變量 Request ,并且方法的實(shí)現(xiàn)調(diào)用 Request 的實(shí)現(xiàn)。然后,將 RequestFacade上轉(zhuǎn)為 ServletRequest 傳給 servlet 的 service 方法,這樣即使在 servlet 中被下轉(zhuǎn)為 RequestFacade ,也不能訪問(wèn)私有成員變量對(duì)象中的方法。既用了 Request ,又能防止其中方法被不合理的訪問(wèn)。


5.6 組合模式 day04

5.6.1 概述

對(duì)于這個(gè)圖片肯定會(huì)非常熟悉,上圖我們可以看做是一個(gè)文件系統(tǒng),對(duì)于這樣的結(jié)構(gòu)我們稱之為樹(shù)形結(jié)構(gòu)。在樹(shù)形結(jié)構(gòu)中可以通過(guò)調(diào)用某個(gè)方法來(lái)遍歷整個(gè)樹(shù),當(dāng)我們找到某個(gè)葉子節(jié)點(diǎn)后,就可以對(duì)葉子節(jié)點(diǎn)進(jìn)行相關(guān)的操作??梢詫⑦@顆樹(shù)理解成一個(gè)大的容器,容器里面包含很多的成員對(duì)象,這些成員對(duì)象既可是容器對(duì)象也可以是葉子對(duì)象。但是由于容器對(duì)象和葉子對(duì)象在功能上面的區(qū)別,使得我們?cè)?strong>使用的過(guò)程中必須要區(qū)分容器對(duì)象和葉子對(duì)象,但是這樣就會(huì)給客戶帶來(lái)不必要的麻煩,作為客戶而已,它始終希望能夠一致的對(duì)待容器對(duì)象和葉子對(duì)象。

定義:

又名部分整體模式,是用于把一組相似的對(duì)象當(dāng)作一個(gè)單一的對(duì)象。組合模式依據(jù)樹(shù)形結(jié)構(gòu)來(lái)組合對(duì)象,用來(lái)表示部分以及整體層次。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它創(chuàng)建了對(duì)象組的樹(shù)形結(jié)構(gòu)

5.6.2 結(jié)構(gòu)

組合模式主要包含三種角色:

  • 抽象根節(jié)點(diǎn)(Component):定義系統(tǒng)各層次對(duì)象的共有方法和屬性,可以預(yù)先定義一些默認(rèn)行為和屬性。
  • 樹(shù)枝節(jié)點(diǎn)(Composite):定義樹(shù)枝節(jié)點(diǎn)的行為,存儲(chǔ)子節(jié)點(diǎn)組合樹(shù)枝節(jié)點(diǎn)和葉子節(jié)點(diǎn)形成一個(gè)樹(shù)形結(jié)構(gòu)。
  • 葉子節(jié)點(diǎn)(Leaf):葉子節(jié)點(diǎn)對(duì)象,其下再無(wú)分支,是系統(tǒng)層次遍歷的最小單位。

5.6.3 案例實(shí)現(xiàn)

【例】軟件菜單

如下圖,我們?cè)谠L問(wèn)別的一些管理系統(tǒng)時(shí),經(jīng)??梢钥吹筋愃频牟藛?。

一個(gè)菜單可以包含菜單項(xiàng)(菜單項(xiàng)是指不再包含其他內(nèi)容的菜單條目),也可以包含帶有其他菜單項(xiàng)的菜單,因此使用組合模式描述菜單就很恰當(dāng),我們的需求是針對(duì)一個(gè)菜單,打印出其包含的所有菜單以及菜單項(xiàng)的名稱。

要實(shí)現(xiàn)該案例,我們先畫(huà)出類圖:

代碼實(shí)現(xiàn):

不管是菜單還是菜單項(xiàng),都應(yīng)該繼承自統(tǒng)一的接口,這里姑且將這個(gè)統(tǒng)一的接口稱為菜單組件。

//菜單組件  不管是菜單還是菜單項(xiàng),都應(yīng)該繼承該類
public abstract class MenuComponent {protected String name;protected int level;//添加菜單public void add(MenuComponent menuComponent){throw new UnsupportedOperationException();}//移除菜單public void remove(MenuComponent menuComponent){throw new UnsupportedOperationException();}//獲取指定的子菜單public MenuComponent getChild(int i){throw new UnsupportedOperationException();}//獲取菜單名稱public String getName(){return name;}public void print(){throw new UnsupportedOperationException();}
}

這里的MenuComponent定義為抽象類,因?yàn)橛幸恍?span style="color:#c21c13;">共有的屬性和行為要在該類中實(shí)現(xiàn),Menu和MenuItem類就可以只覆蓋自己感興趣的方法,而不用搭理不需要或者不感興趣的方法,舉例來(lái)說(shuō),Menu類可以包含子菜單,因此需要覆蓋add()、remove()、getChild()方法,但是MenuItem就不應(yīng)該有這些方法。這里給出的默認(rèn)實(shí)現(xiàn)是拋出異常,你也可以根據(jù)自己的需要改寫(xiě)默認(rèn)實(shí)現(xiàn)。

public class Menu extends MenuComponent {//菜單可以有 多個(gè)子菜單 或者 子菜單項(xiàng)private List<MenuComponent> menuComponentList;public Menu(String name,int level){this.level = level;this.name = name;menuComponentList = new ArrayList<MenuComponent>();}@Overridepublic void add(MenuComponent menuComponent) {menuComponentList.add(menuComponent);}@Overridepublic void remove(MenuComponent menuComponent) {menuComponentList.remove(menuComponent);}@Overridepublic MenuComponent getChild(int i) {return menuComponentList.get(i);}@Overridepublic void print() {for (int i = 1; i < level; i++) {System.out.print("--");}System.out.println(name);for (MenuComponent menuComponent : menuComponentList) {menuComponent.print();}}
}

Menu類已經(jīng)實(shí)現(xiàn)了除了getName方法的其他所有方法,因?yàn)?span style="background-color:#e6d6f0;">Menu類具有添加菜單,移除菜單和獲取子菜單的功能。

public class MenuItem extends MenuComponent {public MenuItem(String name,int level) {this.name = name;this.level = level;}@Overridepublic void print() {for (int i = 1; i < level; i++) {System.out.print("--");}System.out.println(name);}
}

MenuItem是菜單項(xiàng),不能再有子菜單,所以添加菜單,移除菜單和獲取子菜單的功能并不能實(shí)現(xiàn)。

5.6.4 組合模式的分類

在使用組合模式時(shí),根據(jù)抽象構(gòu)件類的定義形式,我們可將組合模式分為透明組合模式和安全組合模式兩種形式。

  • 透明組合模式

透明組合模式中,抽象根節(jié)點(diǎn)角色中聲明了所有用于管理成員對(duì)象的方法,比如在示例中 MenuComponent 聲明了 addremove 、getChild 方法,這樣做的好處是確保所有的構(gòu)件類都有相同的接口。透明組合模式也是組合模式的標(biāo)準(zhǔn)形式。

透明組合模式的缺點(diǎn)是不夠安全,因?yàn)槿~子對(duì)象和容器對(duì)象在本質(zhì)上是有區(qū)別的,葉子對(duì)象不可能有下一個(gè)層次的對(duì)象,即不可能包含成員對(duì)象,因此為其提供 add()、remove() 等方法是沒(méi)有意義的,這在編譯階段不會(huì)出錯(cuò),但在運(yùn)行階段如果調(diào)用這些方法可能會(huì)出錯(cuò)(如果沒(méi)有提供相應(yīng)的錯(cuò)誤處理代碼)

  • 安全組合模式

在安全組合模式中,在抽象構(gòu)件角色中沒(méi)有聲明任何用于管理成員對(duì)象的方法,而是在樹(shù)枝節(jié)點(diǎn) Menu 類中聲明并實(shí)現(xiàn)這些方法。

安全組合模式的缺點(diǎn)是不夠透明,因?yàn)槿~子構(gòu)件和容器構(gòu)件具有不同的方法,且容器構(gòu)件中那些用于管理成員對(duì)象的方法沒(méi)有在抽象構(gòu)件類中定義,因此客戶端不能完全針對(duì)抽象編程,必須有區(qū)別地對(duì)待葉子構(gòu)件和容器構(gòu)件。

5.6.5 優(yōu)點(diǎn)

  • 組合模式可以清楚地定義分層次的復(fù)雜對(duì)象,表示對(duì)象的全部或部分層次,它讓客戶端忽略了層次的差異,方便對(duì)整個(gè)層次結(jié)構(gòu)進(jìn)行控制。
  • 客戶端可以一致地使用一個(gè)組合結(jié)構(gòu)或其中單個(gè)對(duì)象,不必關(guān)心處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu),簡(jiǎn)化了客戶端代碼。
  • 在組合模式中增加新的樹(shù)枝節(jié)點(diǎn)和葉子節(jié)點(diǎn)都很方便,無(wú)須對(duì)現(xiàn)有類庫(kù)進(jìn)行任何修改,符合“開(kāi)閉原則”。
  • 組合模式為樹(shù)形結(jié)構(gòu)的面向?qū)ο髮?shí)現(xiàn)提供了一種靈活的解決方案,通過(guò)葉子節(jié)點(diǎn)和樹(shù)枝節(jié)點(diǎn)的遞歸組合,可以形成復(fù)雜的樹(shù)形結(jié)構(gòu),但對(duì)樹(shù)形結(jié)構(gòu)的控制卻非常簡(jiǎn)單。

5.6.6 使用場(chǎng)景

組合模式正是應(yīng)樹(shù)形結(jié)構(gòu)而生,所以組合模式的使用場(chǎng)景就是出現(xiàn)樹(shù)形結(jié)構(gòu)的地方。比如:文件目錄顯示,多級(jí)目錄呈現(xiàn)等樹(shù)形結(jié)構(gòu)數(shù)據(jù)的操作。

5.7 享元模式(無(wú))

5.7.1 概述

定義:

運(yùn)用共享技術(shù)來(lái)有效地支持大量細(xì)粒度對(duì)象的復(fù)用。它通過(guò)共享已經(jīng)存在的對(duì)象來(lái)大幅度減少需要?jiǎng)?chuàng)建的對(duì)象數(shù)量、避免大量相似對(duì)象的開(kāi)銷,從而提高系統(tǒng)資源的利用率。

5.7.2 結(jié)構(gòu)

享元(Flyweight )模式中存在以下兩種狀態(tài):

  1. 內(nèi)部狀態(tài),即不會(huì)隨著環(huán)境的改變而改變的可共享部分。
  2. 外部狀態(tài),指隨環(huán)境改變而改變的不可以共享的部分。享元模式的實(shí)現(xiàn)要領(lǐng)就是區(qū)分應(yīng)用中的這兩種狀態(tài),并將外部狀態(tài)外部化。

享元模式的主要有以下角色:

  • 抽象享元角色(Flyweight):通常是一個(gè)接口或抽象類,在抽象享元類中聲明了具體享元類公共的方法,這些方法可以向外界提供享元對(duì)象的內(nèi)部數(shù)據(jù)(內(nèi)部狀態(tài)),同時(shí)也可以通過(guò)這些方法來(lái)設(shè)置外部數(shù)據(jù)(外部狀態(tài))。
  • 具體享元(Concrete Flyweight)角色 :它實(shí)現(xiàn)了抽象享元類,稱為享元對(duì)象;在具體享元類中為內(nèi)部狀態(tài)提供了存儲(chǔ)空間。通常我們可以結(jié)合單例模式來(lái)設(shè)計(jì)具體享元類,為每一個(gè)具體享元類提供唯一的享元對(duì)象。
  • 非享元(Unsharable Flyweight)角色 :并不是所有的抽象享元類的子類都需要被共享,不能被共享的子類可設(shè)計(jì)為非共享具體享元類;當(dāng)需要一個(gè)非共享具體享元類的對(duì)象時(shí)可以直接通過(guò)實(shí)例化創(chuàng)建。
  • 享元工廠(Flyweight Factory)角色 :負(fù)責(zé)創(chuàng)建和管理享元角色。當(dāng)客戶對(duì)象請(qǐng)求一個(gè)享元對(duì)象時(shí),享元工廠檢査系統(tǒng)中是否存在符合要求的享元對(duì)象,如果存在則提供給客戶;如果不存在的話,則創(chuàng)建一個(gè)新的享元對(duì)象。

5.7.3 案例實(shí)現(xiàn)

【例】俄羅斯方塊

下面的圖片是眾所周知的俄羅斯方塊中的一個(gè)個(gè)方塊,如果在俄羅斯方塊這個(gè)游戲中,每個(gè)不同的方塊都是一個(gè)實(shí)例對(duì)象,這些對(duì)象就要占用很多的內(nèi)存空間,下面利用享元模式進(jìn)行實(shí)現(xiàn)。

先來(lái)看類圖:

代碼如下:

俄羅斯方塊有不同的形狀,我們可以對(duì)這些形狀向上抽取出AbstractBox,用來(lái)定義共性的屬性和行為。

public abstract class AbstractBox {public abstract String getShape();public void display(String color) {System.out.println("方塊形狀:" + this.getShape() + " 顏色:" + color);}
}

接下來(lái)就是定義不同的形狀了,IBox類、LBox類、OBox類等。

public class IBox extends AbstractBox {@Overridepublic String getShape() {return "I";}
}public class LBox extends AbstractBox {@Overridepublic String getShape() {return "L";}
}public class OBox extends AbstractBox {@Overridepublic String getShape() {return "O";}
}

提供了一個(gè)工廠類(BoxFactory),用來(lái)管理享元對(duì)象(也就是AbstractBox子類對(duì)象),該工廠類對(duì)象只需要一個(gè),所以可以使用單例模式。并給工廠類提供一個(gè)獲取形狀的方法。

public class BoxFactory {private static HashMap<String, AbstractBox> map;private BoxFactory() {map = new HashMap<String, AbstractBox>();AbstractBox iBox = new IBox();AbstractBox lBox = new LBox();AbstractBox oBox = new OBox();map.put("I", iBox);map.put("L", lBox);map.put("O", oBox);}public static final BoxFactory getInstance() {return SingletonHolder.INSTANCE;}private static class SingletonHolder {private static final BoxFactory INSTANCE = new BoxFactory();}public AbstractBox getBox(String key) {return map.get(key);}
}

5.7.5 優(yōu)缺點(diǎn)和使用場(chǎng)景

1,優(yōu)點(diǎn)

  • 極大減少內(nèi)存中相似或相同對(duì)象數(shù)量,節(jié)約系統(tǒng)資源,提供系統(tǒng)性能
  • 享元模式中的外部狀態(tài)相對(duì)獨(dú)立,且不影響內(nèi)部狀態(tài)

2,缺點(diǎn):

為了使對(duì)象可以共享,需要將享元對(duì)象的部分狀態(tài)外部化,分離內(nèi)部狀態(tài)和外部狀態(tài),使程序邏輯復(fù)雜

3,使用場(chǎng)景:

  • 一個(gè)系統(tǒng)有大量相同或者相似的對(duì)象,造成內(nèi)存的大量耗費(fèi)。
  • 對(duì)象的大部分狀態(tài)都可以外部化,可以將這些外部狀態(tài)傳入對(duì)象中。
  • 在使用享元模式時(shí)需要維護(hù)一個(gè)存儲(chǔ)享元對(duì)象的享元池,而這需要耗費(fèi)一定的系統(tǒng)資源,因此,應(yīng)當(dāng)在需要多次重復(fù)使用享元對(duì)象時(shí)才值得使用享元模式。

5.7.6 JDK源碼解析

Integer類使用了享元模式。我們先看下面的例子:

public class Demo {public static void main(String[] args) {Integer i1 = 127;Integer i2 = 127;System.out.println("i1和i2對(duì)象是否是同一個(gè)對(duì)象?" + (i1 == i2));Integer i3 = 128;Integer i4 = 128;System.out.println("i3和i4對(duì)象是否是同一個(gè)對(duì)象?" + (i3 == i4));}
}

運(yùn)行上面代碼,結(jié)果如下:

為什么第一個(gè)輸出語(yǔ)句輸出的是true,第二個(gè)輸出語(yǔ)句輸出的是false?通過(guò)反編譯軟件進(jìn)行反編譯,代碼如下:

public class Demo {public static void main(String[] args) {Integer i1 = Integer.valueOf((int)127);Integer i2 Integer.valueOf((int)127);System.out.println((String)new StringBuilder().append((String)"i1\u548ci2\u5bf9\u8c61\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1f").append((boolean)(i1 == i2)).toString());Integer i3 = Integer.valueOf((int)128);Integer i4 = Integer.valueOf((int)128);System.out.println((String)new StringBuilder().append((String)"i3\u548ci4\u5bf9\u8c61\u662f\u5426\u662f\u540c\u4e00\u4e2a\u5bf9\u8c61\uff1f").append((boolean)(i3 == i4)).toString());}
}

上面代碼可以看到,直接給Integer類型的變量賦值基本數(shù)據(jù)類型數(shù)據(jù)的操作底層使用的是 valueOf() ,所以只需要看該方法即可

public final class Integer extends Number implements Comparable<Integer> {public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {int h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}}
}

可以看到 Integer 默認(rèn)先創(chuàng)建并緩存 -128 ~ 127 之間數(shù)的 Integer 對(duì)象,當(dāng)調(diào)用 valueOf 時(shí)如果參數(shù)在 -128 ~ 127 之間則計(jì)算下標(biāo)并從緩存中返回,否則創(chuàng)建一個(gè)新的 Integer 對(duì)象。

非常感謝您閱讀到這里,創(chuàng)作不易!如果這篇文章對(duì)您有幫助,希望能留下您的點(diǎn)贊👍 關(guān)注💖 收藏 💕評(píng)論💬感謝支持!!!

聽(tīng)說(shuō) 三連能夠給人 帶來(lái)好運(yùn)!更有可能年入百w,進(jìn)入大廠,上岸

http://m.risenshineclean.com/news/46980.html

相關(guān)文章:

  • 大型網(wǎng)站制作建網(wǎng)站專業(yè)
  • 武漢網(wǎng)站開(kāi)發(fā)建設(shè)湖北seo
  • 淘寶網(wǎng)網(wǎng)站建設(shè)目的網(wǎng)站運(yùn)營(yíng)策劃書(shū)
  • 凡科網(wǎng)站產(chǎn)品導(dǎo)航怎么做萌新seo
  • 企業(yè)如何做網(wǎng)站推廣公司百度官網(wǎng)優(yōu)化
  • 好多個(gè)人網(wǎng)站做經(jīng)營(yíng)性網(wǎng)站電商平臺(tái)運(yùn)營(yíng)
  • 用凡科做網(wǎng)站可靠嗎外國(guó)網(wǎng)站怎么進(jìn)入
  • 網(wǎng)站 f型軟文營(yíng)銷的案例
  • 如何做酒店網(wǎng)站設(shè)計(jì)uc瀏覽器關(guān)鍵詞排名優(yōu)化
  • 揚(yáng)州高郵網(wǎng)站建設(shè)上海網(wǎng)站建設(shè)哪家好
  • 南江縣建設(shè)局網(wǎng)站企業(yè)線上培訓(xùn)平臺(tái)有哪些
  • 網(wǎng)站關(guān)鍵詞排名全掉了seo優(yōu)化大公司排名
  • 照明網(wǎng)站建設(shè)新媒體
  • 公眾號(hào)做電影網(wǎng)站營(yíng)銷伎巧第一季
  • 東莞網(wǎng)絡(luò)優(yōu)化哪家強(qiáng)seo排名點(diǎn)擊軟件運(yùn)營(yíng)
  • 家居網(wǎng)站建設(shè)的需求分析今日新聞簡(jiǎn)報(bào)
  • 安吉城鄉(xiāng)建設(shè)局網(wǎng)站百度推廣登陸網(wǎng)址
  • 聊城網(wǎng)站改版搜索引擎營(yíng)銷與seo優(yōu)化
  • 成人版嗶哩嗶哩bilibili邢臺(tái)市seo服務(wù)
  • 網(wǎng)站建設(shè)專業(yè)簡(jiǎn)介優(yōu)化營(yíng)商環(huán)境心得體會(huì)個(gè)人
  • 青田網(wǎng)站做服裝找工作aso優(yōu)化貼吧
  • 六安哪家做網(wǎng)站好什么平臺(tái)打廣告比較好免費(fèi)的
  • 怎么用jsp做網(wǎng)站b站黃頁(yè)推廣
  • 中國(guó)建設(shè)行業(yè)網(wǎng)黑帽seo什么意思
  • 郴州新網(wǎng)最新招聘信息奉節(jié)縣關(guān)鍵詞seo排名優(yōu)化
  • 建設(shè)網(wǎng)站的公司要什么資質(zhì)百度官網(wǎng)認(rèn)證申請(qǐng)
  • 免費(fèi)域名網(wǎng)站建設(shè)站長(zhǎng)之家域名解析
  • 設(shè)計(jì)網(wǎng)站推薦室內(nèi)排名優(yōu)化方案
  • 寶塔 wordpress 404蘭州seo公司
  • 女性時(shí)尚網(wǎng)站模板鄒平縣seo網(wǎng)頁(yè)優(yōu)化外包