摘要:為了挽救這一點,這篇博客將用一個簡單有效的例子來解釋組合模式。唯一需要記住的是組合模式通常用在一個樹結構的遞歸操作上。這個接口我們命名為,對應于組合模式中的。這種多米諾骨牌效應也是組合模式的一個特點。
前言
設計模式可能是博客圈最熱門的話題之一。但是,用來說明每個設計模式的例子通常不是很形象。為了挽救這一點,這篇博客將用一個簡單有效的例子來解釋組合模式。
我們不會再重復解釋這個模型的概念。唯一需要記住的是組合模式通常用在一個樹結構的遞歸操作上。
組合模式例子假設有一棟建筑,這個建筑有幾層樓,每層樓有幾個房間。
這個建筑的神奇之處在于,它沒有一個總開關。因此,當需要關閉或是開啟整棟樓的燈時,就不得不逐層逐個房間按動開關。
為了改變這種情況,我們需要首先定義一個包含開關燈操作的基本接口。這個接口我們命名為Component,對應于組合模式中的Component。
public interface Component { void switchLightsOn(); void switchLightsOff(); }
接著,我們定義表示建筑的類Building,Floor和Room。每個類實現該接口,并且實現的邏輯如下:
Building的開關燈操作意味著整棟樓都將開燈或關燈
Floor的開關燈操作意味著整層樓的開燈或關燈
Room的開關燈操作意味著該房間的開燈或關燈
以下是三個類的內容:
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; } }
補充說明一下:
出于方便,Building類和Floor類直接繼承了ArrayList來獲得其容器的功能
Building將關燈的操作傳遞給其下所有的樓層。類似的,每個樓層將關燈的操作傳遞給每個房間。這種遞歸傳遞時組合模式獨有的一個特點。
總體的效果是Building上的行為啟動了一系列操作并傳遞給Floors和Rooms。這種多米諾骨牌效應也是組合模式的一個特點。
看一下具體的運行情況。首先,我們需要新建一個Building(默認情況下,燈是關閉狀態)。之后,調用建筑的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()); } } } }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注我的微信公眾號!將會不定期的發放福利哦~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68520.html
摘要:根本上來說,這意味著不僅要將整個應用程序分解,而且要將任何一個服務器中的各個部分分解為多個模塊化容器,這些容器易于參數化和重復使用。在中,這種模塊化容器服務的實施者是。一個是指一組共享文件系統,內核命名空間和地址的一組容器。 過去幾年容器逐漸成為了打包和部署代碼的流行的方式。容器鏡像解決很多現有的打包和部署工具所帶來的問題,初次以外,還為我們提供了構建分布式應用的全新的思路。就如SOA...
摘要:因此,誤解幾乎是與之俱來的。這是完全錯誤的。就像所強調的,對于一個被稱作的來說,狀態轉移管理是一個必須要完成的需求。你可以將其稱為或是,但是請不要把它叫做。 2000年的時候,Douglas Crockford聲明JavaScript是最被誤解的編程語言。這種誤解來源于不良的命名規范,錯誤設計,非標準模式等等。因此,誤解幾乎是與之俱來的。 我也在關于Restful架構上發表了一個相似的...
摘要:什么是仿射變換一組設備無關的坐標被用來將所有的坐標信息傳遞給對象。對象作為對象狀態的一部分。類代表一個的仿射變化,將一組的坐標進行線性映射到另一組保留了平行關系和豎直關系的坐標中。 什么是仿射變換 一組設備無關的坐標被用來將所有的坐標信息傳遞給Graphics2D對象。AffineTransform對象作為Graphics2D對象狀態的一部分。該對象定義了如何將用戶空間的坐標轉化為設備...
摘要:我們將使用單個線程管理任務放入隊列的操作以及從隊列中取出的操作。同時這個線程會持續的管理隊列。另一個線程將用來創建,它將一直運行知道服務器終止。此線程永遠不會過期,有助于實現持續監控。這些請求將會自動的被獲取,并在線程中繼續處理。 在Java中,BlockingQueue接口位于java.util.concurrent包下。阻塞隊列主要用來線程安全的實現生產者-消費者模型。他們可以使用...
摘要:由于需要跨進程訪問網絡上的高速緩存,因此延遲,故障和對象序列化會導致性能下降。應用程序高速緩存會自動清除條目以保持其內存占用。緩存統計高速緩存統計信息可幫助識別高速緩存的運行狀況并提供有關高速緩存行為和性能的信息。 前言 這篇文章探索了現有的各種JAVA緩存基數,它們對各種場景下提高應用的性能起著重要的作用。 近十年來,信息技術極高的提升了業務流程,它已經成為了全球企業的戰略性方案。它...
閱讀 5035·2021-07-25 21:37
閱讀 682·2019-08-30 15:53
閱讀 3349·2019-08-29 18:47
閱讀 686·2019-08-29 15:39
閱讀 2130·2019-08-29 13:12
閱讀 1796·2019-08-29 12:43
閱讀 2977·2019-08-26 11:52
閱讀 1889·2019-08-26 10:15