java手動切換成獨立顯卡_JAVA設計模式之調停者模式

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述調停者(Mediator)模式的:

調停者模式是對象的行為模式。調停者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯引用。從而使它們可以較松散地耦合。當這些對象中的某些對象之間的相互作用發生改變時,不會立即影響到其他的一些對象之間的相互作用。從而保證這些相互作用可以彼此獨立地變化。

為什么需要調停者

如下圖所示,這個示意圖中有大量的對象,這些對象既會影響別的對象,又會被別的對象所影響,因此常常叫做同事(Colleague)對象。這些同事對象通過彼此的相互作用形成系統的行為。從圖中可以看出,幾乎每一個對象都需要與其他的對象發生相互作用,而這種相互作用表現為一個對象與另一個對象的直接耦合。這就是過度耦合的系統。

bufGW7duiV7ulIF1wY7RVsb+QA1DEEQBMkqqGEIgiBIVkENQxAEQbIKahiCIAiSVf4fuI2WhGEFLvoAAAAASUVORK5CYII=

通過引入調停者對象(Mediator),可以將系統的網狀結構變成以中介者為中心的星形結構,如下圖所示。在這個星形結構中,同事對象不再通過直接的聯系與另一個對象發生相互作用;相反的,它通過調停者對象與另一個對象發生相互作用。調停者對象的存在保證了對象結構上的穩定,也就是說,系統的結構不會因為新對象的引入造成大量的修改工作。

B92VXAeVUNd2AAAAAElFTkSuQmCC  一個好的面向對象的設計可以使對象之間增加協作性(Collaboration),減少耦合度(Couping)。一個深思熟慮的設計會把一個系統分解為一群相互協作的同事對象,然后給每一個同事對象以獨特的責任,恰當的配置它們之間的協作關系,使它們可以在一起工作。

如果沒有主板

大家都知道,電腦里面各個配件之間的交互,主要是通過主板來完成的。如果電腦里面沒有了主板,那么各個配件之間就必須自行相互交互,以互相傳送數據。而且由于各個配件的接口不同,相互之間交互時,還必須把數據接口進行轉換才能匹配上。

3XEqgAAAAJJREFUWLolLTB0AAAAAElFTkSuQmCC

所幸是有了主板,各個配件的交互完全通過主板來完成,每個配件都只需要和主板交互,而主板知道如何跟所有的配件打交道,這樣就簡單多了。

wfrZbkpyBoeVgAAAABJRU5ErkJggg==

調停者模式的結構

調停者模式的示意性類圖如下所示:

wACiREvU8ZO9wAAAABJRU5ErkJggg==

調停者模式包括以下角色:

●  抽象調停者(Mediator)角色:定義出同事對象到調停者對象的接口,其中主要方法是一個(或多個)事件方法。

●  具體調停者(ConcreteMediator)角色:實現了抽象調停者所聲明的事件方法。具體調停者知曉所有的具體同事類,并負責具體的協調各同事對象的交互關系。

●  抽象同事類(Colleague)角色:定義出調停者到同事對象的接口。同事對象只知道調停者而不知道其余的同事對象。

●  具體同事類(ConcreteColleague)角色:所有的具體同事類均從抽象同事類繼承而來。實現自己的業務,在需要與其他同事通信的時候,就與持有的調停者通信,調停者會負責與其他的同事交互。

源代碼

抽象調停者類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public interfaceMediator {/*** 同事對象在自身改變的時候來通知調停者方法

* 讓調停者去負責相應的與其他同事對象的交互*/

public voidchanged(Colleague c);

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

具體調停者類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class ConcreteMediator implementsMediator {//持有并維護同事A

privateConcreteColleagueA colleagueA;//持有并維護同事B

privateConcreteColleagueB colleagueB;public voidsetColleagueA(ConcreteColleagueA colleagueA) {this.colleagueA =colleagueA;

}public voidsetColleagueB(ConcreteColleagueB colleagueB) {this.colleagueB =colleagueB;

}

@Overridepublic voidchanged(Colleague c) {/*** 某一個同事類發生了變化,通常需要與其他同事交互

* 具體協調相應的同事對象來實現協作行為*/}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

抽象同事類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public abstract classColleague {//持有一個調停者對象

privateMediator mediator;/*** 構造函數*/

publicColleague(Mediator mediator){this.mediator =mediator;

}/*** 獲取當前同事類對應的調停者對象*/

publicMediator getMediator() {returnmediator;

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

具體同事類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class ConcreteColleagueA extendsColleague {publicConcreteColleagueA(Mediator mediator) {super(mediator);

}/*** 示意方法,執行某些操作*/

public voidoperation(){//在需要跟其他同事通信的時候,通知調停者對象

getMediator().changed(this);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class ConcreteColleagueB extendsColleague {publicConcreteColleagueB(Mediator mediator) {super(mediator);

}/*** 示意方法,執行某些操作*/

public voidoperation(){//在需要跟其他同事通信的時候,通知調停者對象

getMediator().changed(this);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

使用電腦來看電影

在日常生活中,我們經常使用電腦來看電影,把這個過程描述出來,簡化后假定會有如下的交互過程:

(1)首先是光驅要讀取光盤上的數據,然后告訴主板,它的狀態改變了。

(2)主板去得到光驅的數據,把這些數據交給CPU進行分析處理。

(3)CPU處理完后,把數據分成了視頻數據和音頻數據,通知主板,它處理完了。

(4)主板去得到CPU處理過后的數據,分別把數據交給顯卡和聲卡,去顯示出視頻和發出聲音。

要使用調停者模式來實現示例,那就要區分出同事對象和調停者對象。很明顯,主板是調停者,而光驅、聲卡、CPU、顯卡等配件,都是作為同事對象。

SqkkIQQQgghfKSQhBBCCCF8pJCEEEIIIXykkIQQQgghfKSQhBBCCCF8pJCEEEIIIXykkIQQQgghfP4fCfyi5lMYBBcAAAAASUVORK5CYII=

源代碼

抽象同事類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public abstract classColleague {//持有一個調停者對象

privateMediator mediator;/*** 構造函數*/

publicColleague(Mediator mediator){this.mediator =mediator;

}/*** 獲取當前同事類對應的調停者對象*/

publicMediator getMediator() {returnmediator;

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

同事類——光驅

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class CDDriver extendsColleague{//光驅讀取出來的數據

private String data = "";/*** 構造函數*/

publicCDDriver(Mediator mediator) {super(mediator);

}/*** 獲取光盤讀取出來的數據*/

publicString getData() {returndata;

}/*** 讀取光盤*/

public voidreadCD(){//逗號前是視頻顯示的數據,逗號后是聲音

this.data = "One Piece,海賊王我當定了";//通知主板,自己的狀態發生了改變

getMediator().changed(this);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

同事類——CPU

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class CPU extendsColleague {//分解出來的視頻數據

private String videoData = "";//分解出來的聲音數據

private String soundData = "";/*** 構造函數*/

publicCPU(Mediator mediator) {super(mediator);

}/*** 獲取分解出來的視頻數據*/

publicString getVideoData() {returnvideoData;

}/*** 獲取分解出來的聲音數據*/

publicString getSoundData() {returnsoundData;

}/*** 處理數據,把數據分成音頻和視頻的數據*/

public voidexecuteData(String data){//把數據分解開,前面是視頻數據,后面是音頻數據

String[] array = data.split(",");this.videoData = array[0];this.soundData = array[1];//通知主板,CPU完成工作

getMediator().changed(this);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

同事類——顯卡

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class VideoCard extendsColleague {/*** 構造函數*/

publicVideoCard(Mediator mediator) {super(mediator);

}/*** 顯示視頻數據*/

public voidshowData(String data){

System.out.println("您正在觀看的是:" +data);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

同事類——聲卡

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class SoundCard extendsColleague {/*** 構造函數*/

publicSoundCard(Mediator mediator) {super(mediator);

}/*** 按照聲頻數據發出聲音*/

public voidsoundData(String data){

System.out.println("畫外音:" +data);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

抽象調停者類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public interfaceMediator {/*** 同事對象在自身改變的時候來通知調停者方法

* 讓調停者去負責相應的與其他同事對象的交互*/

public voidchanged(Colleague c);

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

具體調停者類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class MainBoard implementsMediator {//需要知道要交互的同事類——光驅類

private CDDriver cdDriver = null;//需要知道要交互的同事類——CPU類

private CPU cpu = null;//需要知道要交互的同事類——顯卡類

private VideoCard videoCard = null;//需要知道要交互的同事類——聲卡類

private SoundCard soundCard = null;public voidsetCdDriver(CDDriver cdDriver) {this.cdDriver =cdDriver;

}public voidsetCpu(CPU cpu) {this.cpu =cpu;

}public voidsetVideoCard(VideoCard videoCard) {this.videoCard =videoCard;

}public voidsetSoundCard(SoundCard soundCard) {this.soundCard =soundCard;

}

@Overridepublic voidchanged(Colleague c) {if(c instanceofCDDriver){//表示光驅讀取數據了

this.opeCDDriverReadData((CDDriver)c);

}else if(c instanceofCPU){this.opeCPU((CPU)c);

}

}/*** 處理光驅讀取數據以后與其他對象的交互*/

private voidopeCDDriverReadData(CDDriver cd){//先獲取光驅讀取的數據

String data =cd.getData();//把這些數據傳遞給CPU進行處理

cpu.executeData(data);

}/*** 處理CPU處理完數據后與其他對象的交互*/

private voidopeCPU(CPU cpu){//先獲取CPU處理后的數據

String videoData =cpu.getVideoData();

String soundData=cpu.getSoundData();//把這些數據傳遞給顯卡和聲卡展示出來

videoCard.showData(videoData);

soundCard.soundData(soundData);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

客戶端類

48304ba5e6f9fe08f3fa1abda7d326ab.png

public classClient {public static voidmain(String[] args) {//創建調停者——主板

MainBoard mediator = newMainBoard();//創建同事類

CDDriver cd = newCDDriver(mediator);

CPU cpu= newCPU(mediator);

VideoCard vc= newVideoCard(mediator);

SoundCard sc= newSoundCard(mediator);//讓調停者知道所有同事

mediator.setCdDriver(cd);

mediator.setCpu(cpu);

mediator.setVideoCard(vc);

mediator.setSoundCard(sc);//開始看電影,把光盤放入光驅,光驅開始讀盤

cd.readCD();

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

運行結果如下:

weY2q9954zdoAAAAABJRU5ErkJggg==

調停者模式的優點

●  松散耦合

調停者模式通過把多個同事對象之間的交互封裝到調停者對象里面,從而使得同事對象之間松散耦合,基本上可以做到互補依賴。這樣一來,同事對象就可以獨立地變化和復用,而不再像以前那樣“牽一處而動全身”了。

● 集中控制交互

多個同事對象的交互,被封裝在調停者對象里面集中管理,使得這些交互行為發生變化的時候,只需要修改調停者對象就可以了,當然如果是已經做好的系統,那么就擴展調停者對象,而各個同事類不需要做修改。

●  多對多變成一對多

沒有使用調停者模式的時候,同事對象之間的關系通常是多對多的,引入調停者對象以后,調停者對象和同事對象的關系通常變成雙向的一對多,這會讓對象的關系更容易理解和實現。

調停者模式的缺點

調停者模式的一個潛在缺點是,過度集中化。如果同事對象的交互非常多,而且比較復雜,當這些復雜性全部集中到調停者的時候,會導致調停者對象變得十分復雜,而且難于管理和維護。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453500.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453500.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453500.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2018.2.8 php實現qq登陸接口

PHP實現QQ登錄的原理和實現過程 2018-02-08 學習與分享 PHP自學中心 第三方登錄,就是使用大家比較熟悉的比如QQ、微信、微博等第三方軟件登錄自己的網站,這可以免去注冊賬號、快速留住用戶的目的,免去了相對復雜的注冊流程。下邊就給大家講一…

關于積累的一點看法

這是vip那邊發表的一篇帖子,今天整理,發現可能有一點代表性,就再發在這里,供各位同學參考。 壇子里有人討論小公司要不要積累框架的問題,有感而發,寫了點自己的看法,一家之言,歡迎拍…

去除vue項目中的#及其ie9兼容性

一、如何去除vue項目中訪問地址的# vue2中在路由配置中添加mode(vue-cli創建的項目在src/router/index.js) 1 export default new Router({2 mode: history,3 routes: [4 {5 path: /,6 name: menu,7 component: menu,8 …

sendBroadcast與sendStickyBroadcast的區別

前提條件:此處我主要討論兩種廣播在代碼中動態注冊時的一些細節問題。 正常情況下,廣播通常都是執行一次注冊代碼,就會觸發各接收器接收一次,無論是在onCreate里注冊還是onResume里注冊:若在onCreate里注冊&#xff0…

java 線程池 初始大小_為什么tomcat的默認線程池大小如此之大? - java

我注意到默認的tomcat 7線程池大小似乎是200。但是普通的CPU似乎有16個內核。因此只能并行執行16個線程為什么tomcat使用那么多線程。參考方案多年以來,許多單核計算機問世,并且能夠以“偽并行”模式運行功能,也就是說,您可能有16…

Hadoop2.6.0完全分布式安裝

1、修改主機名稱 對master/slave1/slave2同時配置為Master/Slave1/Slave2 masterMaster:~$ sudo gedit /etc/hostname 上述3個虛機結點均需要進行以上步驟 2、填寫主機IP 對master/slave1/slave2同時配置 masterMaster:~$ sudo gedit /etc/hosts 192.168.48.128 master192.168.…

DEX加密效果分析

dex加密目的:保護安卓應用的Java源代碼,避免被惡意分析,技術被竊取準備工具:1、apktool :反編譯apk,提取smali代碼2、dex2jar :將dex轉化為jar文件3、jd-gui :查看jar文件&#xff0…

一些比特率值

比特率 比特率是指將數字聲音由模擬格式轉化成數字格式的采樣率,采樣率越高,還原后的音質就越好。 比特率值與現實音頻對照: 16KBPS電話音質 24KBPS增加電話音質、短波廣播、長波廣播、歐洲制式中波廣播40KBPS美國制式中波廣播56KBPS話…

java asynccontext,超時后的JavaEE 6 AsyncContext行為

What is the exact behavior of AsyncContext after it times out? Does it still run and does it return response using getResponse()?解決方案Java Servlet 3.0 Maintenance Release on page 34 reads:A call to this method - ServletRequest.startAsync(ServletReques…

BZOJ1857:[SCOI2010]傳送帶——題解

http://www.lydsy.com/JudgeOnline/problem.php?id1857 Description 在一個2維平面上有兩條傳送帶,每一條傳送帶可以看成是一條線段。兩條傳送帶分別為線段AB和線段CD。lxhgww在AB上的移動速度為P,在CD上的移動速度為Q,在平面上的移動速度R。…

mnt/sdcard和storage/sdcard的區別

/mnt 目錄,熟悉linux的人都清楚,linux默認掛載外部設備都會掛到這個目錄下面去,如將sd卡掛載上去后,會生成一個/mnt/sdcard 目錄。 storage/sdcard 目錄,這是一個軟鏈接(相當于windows的文件夾的快捷方式&a…

kd樹的原理

kd樹就是一種對k維空間中的實例點進行存儲以便對其進行快速檢索的樹形數據結構,可以運用在k近鄰法中,實現快速k近鄰搜索。構造kd樹相當于不斷地用垂直于坐標軸的超平面將k維空間切分。 ?? 假設數據集\(T\)的大小是\(m*n\),即\(T{x_1,x_2,...x_m}\),其中…

應聘華為的朋友小心了,應聘華為的悲慘遭遇!

以下內容全部真實,為本人親身經歷。可隨時進行當面對質。 本人女朋友,原本是西安一家企業里面的行政助理,工作比較穩定,收入不高,但也基本夠她用了。 一天,我的一個同學(華為員工)說…

力軟 java主從表保存_JAVA常用知識總結(十二)——數據庫(二)

MySQL主從熱備份工作原理簡單的說:就是主服務器上執行過的sql語句會保存在binLog里面,別的從服務器把他同步過來,然后重復執行一遍,那么它們就能一直同步啦。整體上來說,復制有3個步驟:作為主服務器的Maste…

HttpClient和DefaultHttpClient

HttpClient 是接口,DefaultHttpClient是實現這個接口的子類 public interface HttpClient {/*** Obtains the parameters for this client.* These parameters will become defaults for all requests being* executed with this client, and for the parameters of…

Go語言版黑白棋

1、游戲說明2、無邊框窗口實現3、背景圖、最小化、關閉窗口4、界面其它設計5、黑白子提示閃爍效果6、落子7、初始化棋子、改變角色8、倒計時9、吃子10、棋子個數統計、勝負判斷11、機器落子 轉載于:https://www.cnblogs.com/tennysonsky/p/8442827.html

vue使用render渲染jsx

vue&jsx文檔 vue實例屬性 // App.ts import hBtn from ./components/hBtn import hUl from ./components/hUlexport default {data(){return {theme: "mdui-theme-pink",accent: "mdui-theme-accent-pink",users:[aoo, boo, coo]}},methods:{},render(…

java中的多線程有什么意義_Java多線程與并發面試題(小結)

1,什么是線程?線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。程序員可以通過它進行多處理器編程,你可以使用多線程對運算密集型任務提速。比如,如果一個線程完成一…

IT必須掌握的常用命令

一,ping      它是用來檢查網絡是否通暢或者網絡連接速度的命令。作為一個生活在網絡上的管理員或者黑客來說,ping命令是第一個必須掌握的DOS命令,它所利用的原理是這樣的:網絡上的機器都有唯一確定的IP地址,我們…

Callable類

(一) Callable和Runnable比較相似,都可以用來實現線程任務。但callable使用了泛型設計,使用一個V類型值,能夠 在執行結束后返回一個V類型的值。而Runable只會返回一個void,不能夠獲得執行的結果。 &#x…