摘要:為了挽救這一點(diǎn),這篇博客將用一個(gè)簡(jiǎn)單有效的例子來解釋組合模式。唯一需要記住的是組合模式通常用在一個(gè)樹結(jié)構(gòu)的遞歸操作上。這個(gè)接口我們命名為,對(duì)應(yīng)于組合模式中的。這種多米諾骨牌效應(yīng)也是組合模式的一個(gè)特點(diǎn)。
前言
設(shè)計(jì)模式可能是博客圈最熱門的話題之一。但是,用來說明每個(gè)設(shè)計(jì)模式的例子通常不是很形象。為了挽救這一點(diǎn),這篇博客將用一個(gè)簡(jiǎn)單有效的例子來解釋組合模式。
我們不會(huì)再重復(fù)解釋這個(gè)模型的概念。唯一需要記住的是組合模式通常用在一個(gè)樹結(jié)構(gòu)的遞歸操作上。
組合模式例子假設(shè)有一棟建筑,這個(gè)建筑有幾層樓,每層樓有幾個(gè)房間。
這個(gè)建筑的神奇之處在于,它沒有一個(gè)總開關(guān)。因此,當(dāng)需要關(guān)閉或是開啟整棟樓的燈時(shí),就不得不逐層逐個(gè)房間按動(dòng)開關(guān)。
為了改變這種情況,我們需要首先定義一個(gè)包含開關(guān)燈操作的基本接口。這個(gè)接口我們命名為Component,對(duì)應(yīng)于組合模式中的Component。
public interface Component { void switchLightsOn(); void switchLightsOff(); }
接著,我們定義表示建筑的類Building,Floor和Room。每個(gè)類實(shí)現(xiàn)該接口,并且實(shí)現(xiàn)的邏輯如下:
Building的開關(guān)燈操作意味著整棟樓都將開燈或關(guān)燈
Floor的開關(guān)燈操作意味著整層樓的開燈或關(guān)燈
Room的開關(guān)燈操作意味著該房間的開燈或關(guān)燈
以下是三個(gè)類的內(nèi)容:
Buildingpublic class Building extends ArrayListFloorimplements Component{ @Override public void switchLightsOn() { for (Floor floor : this) { floor.switchLightsOn(); } } @Override public void switchLightsOff() { for (Floor floor : this) { floor.switchLightsOff(); } } }
public class Floor extends ArrayListRoomimplements Component { private int floorNumber; public Floor(int floorNumber){ this.floorNumber=floorNumber; } @Override public void switchLightsOn() { for (Room room : this) { room.switchLightsOn(); } } @Override public void switchLightsOff() { for (Room room : this) { room.switchLightsOff(); } } }
public class Room implements Component { private boolean lightsOn = false; private int roomNumber; public Room(int roomNumber){ this.roomNumber=roomNumber; } @Override public void switchLightsOn() { lightsOn = true; } @Override public void switchLightsOff() { lightsOn = false; } public boolean isLightsOn() { return lightsOn; } }
補(bǔ)充說明一下:
出于方便,Building類和Floor類直接繼承了ArrayList來獲得其容器的功能
Building將關(guān)燈的操作傳遞給其下所有的樓層。類似的,每個(gè)樓層將關(guān)燈的操作傳遞給每個(gè)房間。這種遞歸傳遞時(shí)組合模式獨(dú)有的一個(gè)特點(diǎn)。
總體的效果是Building上的行為啟動(dòng)了一系列操作并傳遞給Floors和Rooms。這種多米諾骨牌效應(yīng)也是組合模式的一個(gè)特點(diǎn)。
看一下具體的運(yùn)行情況。首先,我們需要新建一個(gè)Building(默認(rèn)情況下,燈是關(guān)閉狀態(tài))。之后,調(diào)用建筑的switchLightsOn方法,打開建筑中的所有房間的燈。
public class CompositeTest { private Building building; @Before public void createBuilding(){ building = new Building(); //1st floor Floor floor = new Floor(1); floor.add(new Room(11)); floor.add(new Room(12)); building.add(floor); //2nd floor floor = new Floor(2); floor.add(new Room(21)); floor.add(new Room(22)); floor.add(new Room(23)); building.add(floor); //3rd floor floor = new Floor(3); floor.add(new Room(31)); floor.add(new Room(32)); floor.add(new Room(33)); building.add(floor); } @Test public void buildingLightsAreOn(){ //checking that all rooms are off for(Floor floor : building){ for(Room room : floor){ assertEquals(false,room.isLightsOn()); } } building.switchLightsOn(); //checking that all rooms are on for(Floor floor : building){ for(Room room : floor){ assertEquals(true,room.isLightsOn()); } } } }
想要了解更多開發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號(hào)!將會(huì)不定期的發(fā)放福利哦~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68520.html
摘要:根本上來說,這意味著不僅要將整個(gè)應(yīng)用程序分解,而且要將任何一個(gè)服務(wù)器中的各個(gè)部分分解為多個(gè)模塊化容器,這些容器易于參數(shù)化和重復(fù)使用。在中,這種模塊化容器服務(wù)的實(shí)施者是。一個(gè)是指一組共享文件系統(tǒng),內(nèi)核命名空間和地址的一組容器。 過去幾年容器逐漸成為了打包和部署代碼的流行的方式。容器鏡像解決很多現(xiàn)有的打包和部署工具所帶來的問題,初次以外,還為我們提供了構(gòu)建分布式應(yīng)用的全新的思路。就如SOA...
摘要:因此,誤解幾乎是與之俱來的。這是完全錯(cuò)誤的。就像所強(qiáng)調(diào)的,對(duì)于一個(gè)被稱作的來說,狀態(tài)轉(zhuǎn)移管理是一個(gè)必須要完成的需求。你可以將其稱為或是,但是請(qǐng)不要把它叫做。 2000年的時(shí)候,Douglas Crockford聲明JavaScript是最被誤解的編程語言。這種誤解來源于不良的命名規(guī)范,錯(cuò)誤設(shè)計(jì),非標(biāo)準(zhǔn)模式等等。因此,誤解幾乎是與之俱來的。 我也在關(guān)于Restful架構(gòu)上發(fā)表了一個(gè)相似的...
摘要:什么是仿射變換一組設(shè)備無關(guān)的坐標(biāo)被用來將所有的坐標(biāo)信息傳遞給對(duì)象。對(duì)象作為對(duì)象狀態(tài)的一部分。類代表一個(gè)的仿射變化,將一組的坐標(biāo)進(jìn)行線性映射到另一組保留了平行關(guān)系和豎直關(guān)系的坐標(biāo)中。 什么是仿射變換 一組設(shè)備無關(guān)的坐標(biāo)被用來將所有的坐標(biāo)信息傳遞給Graphics2D對(duì)象。AffineTransform對(duì)象作為Graphics2D對(duì)象狀態(tài)的一部分。該對(duì)象定義了如何將用戶空間的坐標(biāo)轉(zhuǎn)化為設(shè)備...
摘要:我們將使用單個(gè)線程管理任務(wù)放入隊(duì)列的操作以及從隊(duì)列中取出的操作。同時(shí)這個(gè)線程會(huì)持續(xù)的管理隊(duì)列。另一個(gè)線程將用來創(chuàng)建,它將一直運(yùn)行知道服務(wù)器終止。此線程永遠(yuǎn)不會(huì)過期,有助于實(shí)現(xiàn)持續(xù)監(jiān)控。這些請(qǐng)求將會(huì)自動(dòng)的被獲取,并在線程中繼續(xù)處理。 在Java中,BlockingQueue接口位于java.util.concurrent包下。阻塞隊(duì)列主要用來線程安全的實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型。他們可以使用...
摘要:由于需要跨進(jìn)程訪問網(wǎng)絡(luò)上的高速緩存,因此延遲,故障和對(duì)象序列化會(huì)導(dǎo)致性能下降。應(yīng)用程序高速緩存會(huì)自動(dòng)清除條目以保持其內(nèi)存占用。緩存統(tǒng)計(jì)高速緩存統(tǒng)計(jì)信息可幫助識(shí)別高速緩存的運(yùn)行狀況并提供有關(guān)高速緩存行為和性能的信息。 前言 這篇文章探索了現(xiàn)有的各種JAVA緩存基數(shù),它們對(duì)各種場(chǎng)景下提高應(yīng)用的性能起著重要的作用。 近十年來,信息技術(shù)極高的提升了業(yè)務(wù)流程,它已經(jīng)成為了全球企業(yè)的戰(zhàn)略性方案。它...
閱讀 5149·2021-07-25 21:37
閱讀 716·2019-08-30 15:53
閱讀 3388·2019-08-29 18:47
閱讀 728·2019-08-29 15:39
閱讀 2178·2019-08-29 13:12
閱讀 1850·2019-08-29 12:43
閱讀 3032·2019-08-26 11:52
閱讀 1936·2019-08-26 10:15