小Y在文章開始之前先回顧一下歷史:三省六部制是西晉以後長期發展形成,至隋朝正式確立,唐朝進一步完善的一種政治制度,反映了中國古代君主專制中央集權制度的進一步完善。那麼小Y今天的主題就來了—如何最大實現“一省六部”(尚書省、吏部、戶部、禮部、兵部、刑部、工部)的效能,Action。
一、前提
尚書省管屬下的六部之間相互協調工作,來張圖展示一下這錯綜複雜、愛恨情仇的關係。
為了文章的簡潔,小Y不得不裁減部門了,把“一省六部”直接縮減為“一省三部”。
三個部門相互依賴的同時它們也有著自己的職能,小Y就有失偏頗地概括了一下:
- 戶部:管理錢財。
- 兵部:掌管兵權。
- 工部:掌管營造工程事項。
二、情景再現
1.天災造成百姓流離失所,餓殍滿地,這下戶部麻煩了,心想著責任不能我一個人擔啊,死都要拉個墊背的。
-
對兵部說:饑民太多,恐防出現暴亂,需要軍隊鎮壓。
-
對工部說:災害損毀房屋太多,需要你們來規劃重建。
2.不長眼睛的蠻夷族要攻打天朝,兵部這下就坐不住了,立馬找來工部和戶部。
-
對工部說:蠻夷族的戰鬥力太強悍了,需要通過一些防禦工事抵禦,這事就交給你們了。
-
對戶部說:要想打勝仗,士兵首先要吃得飽穿得暖,吃穿的錢糧這個重任就非你們莫屬了。
3.皇帝老爺的妃子多了,行宮要大批大批的建,工部就抱怨了,為毛皇帝這毛快活就要累死我們,不行,有苦同吃,有難各自飛,這才是兄弟嘛。
-
對兵部說:陛下要求大規模建行宮,為陛下服務的機會到了哈,調遣大批士兵給我當苦力吧。
-
對戶部說:行官需要設計精美,需要花費的銀子不少,需要你們搜刮多點民脂民膏。
三、出謀劃策
-
方案一:尚書省只掛個管理牌就可以,對下面六個部門的工作不干預,愛咋幹咋幹,關鍵時刻給我功勞就好。
-
以尚書省為中心,底下六個部門在工作上不直接進行交流,統一經過尚書 省(中介者模式)。
四、來波廣告
1.中介模式的定義
用一箇中介物件封裝一系列的物件互動,中介者使各物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。
2.中介模式的角色介紹
-
Mediator 抽象中介者角色
抽象中介者角色定義統一的介面,用於各同事角色之間的通訊。 -
Concrete Mediator 具體中介者角色
具體中介者角色通過協調各同事角色實現協作行為,因此它必須依賴於各個同事角色。 -
Colleague 同事角色
每一個同事角色都知道中介者角色,而且與其他的同事角色通訊的時候,一定要通過中介者角色協作。每個同事類的行為分為兩種:一種是同事本身的行為,比如改變物件本身的狀態,處理自己的行為等,這種行為叫做自發行為,與其他的同事類或中介者沒有任何的依賴;第二種是必須依賴中介者才能完成的行為,叫做依賴方法。
3.中介模式的使用場景
-
在物件導向的程式設計中,物件和物件之間必然會有依賴關係。
-
中介者模式適用於多個物件之間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構。
五、方案的實施
1.方案一
發生事情各個部門自行商量解決。
①戶部
public class Department {
public void dealDisaster(){
System.out.println("戶部:專挑輕活,其他的找別人幹去。");
//需要工部規劃重建
Ministry ministry=new Ministry();
ministry.selfFunction();
//需要兵部調兵遣將鎮壓災民
Defense defense=new Defense();
defense.selfFunction();
}
public void selfFunction(){
System.out.println("戶部:要錢沒問題,我儘量搜刮點民脂民膏。");
}
}
複製程式碼
②兵部
public class Defense {
public void fight(){
System.out.println("我只出人,剩下的找別人幹去。");
//需要戶部搜刮民脂民膏
Department department=new Department();
department.selfFunction();
//需要工部給圖紙建造防禦工事
Ministry ministry=new Ministry();
ministry.selfFunction();
}
public void selfFunction(){
System.out.println("兵部:要人沒問題,我儘量抓多幾個壯丁");
}
}
複製程式碼
③工部
public class Ministry {
public void buildPalace(){
System.out.println("工部:我只畫圖紙,其他的找別人幹去。");
//需要戶部出錢
Department department=new Department();
department.selfFunction();
//需要兵部調兵遣將加入建造
Defense defense=new Defense();
defense.selfFunction();
}
public void selfFunction(){
System.out.println("工部:要建築圖紙沒問題,我儘量複製多幾份");
}
}
複製程式碼
④Client
public class Client {
public static void main(String[] args) {
//發生天災了,戶部麻煩了,需要解決問題
Department department=new Department();
department.dealDisaster();
//要打仗了,兵部的活來了
Defense defense=new Defense();
defense.fight();
//皇帝發話了,工部趕緊建行宮
Ministry ministry=new Ministry();
ministry.buildPalace();
}
}
複製程式碼
輸出的結果為:
//發生天災了,戶部麻煩了,需要解決問題
戶部:專挑輕活,其他的找別人幹去。
工部:要建築圖紙沒問題,我儘量複製多幾份。
兵部:要人沒問題,我儘量抓多幾個壯丁。
//要打仗了,兵部的活來了
兵部:我只出人,剩下的找別人幹去。
戶部:要錢沒問題,我儘量搜刮點民脂民膏。
工部:要建築圖紙沒問題,我儘量複製多幾份。
//皇帝發話了,工部趕緊建行宮
工部:我只畫圖紙,其他的找別人幹去。
戶部:要錢沒問題,我儘量搜刮點民脂民膏。
兵部:要人沒問題,我儘量抓多幾個壯丁。
複製程式碼
三個部門遇到問題都相互協調解決了,沒出什麼么蛾子,尚書省也照樣得到功勞獎勵。從上面的例子發現這三個類是彼此關聯的,每個類都與其他兩個類產生了關聯關係。這樣子缺點就暴露出來了,它們彼此關聯越多,耦合性越大,要想修改一個就得修改一片,這不是物件導向設計所期望的,上面的例子還是僅三個部門的情況,如果實現上圖的六部之間的協調關係,維護起來都要吐血而亡,果斷拋棄。
2.方案二(中介者模式)
UML實現
①抽象中介者(尚書省)
public abstract class AbstractMediator {
protected Department department;
protected Defense defense;
protected Ministry ministry;
public AbstractMediator() {
department = new Department(this);
defense=new Defense(this);
ministry=new Ministry(this);
}
//中介者最重要的方法叫做事件方法,處理多個物件之間的關係
public abstract void dealThing(int code);
}
複製程式碼
②具體中介者
public class Mediator extends AbstractMediator{
public static final int DEPARTMENT_CODE=1;
public static final int DEFENSE_CODE=2;
public static final int MINISTRY_CODE=3;
@Override
public void dealThing(int code) {
switch (code){
case DEPARTMENT_CODE:
this.dealDisaster();
break;
case DEFENSE_CODE:
this.fight();
break;
case MINISTRY_CODE:
this.buildPalace();
break;
}
}
//戶部處理天災
private void dealDisaster(){
System.out.println("戶部:專挑輕活,其他的找別人幹去。");
super.ministry.selfFunction();
super.defense.selfFunction();
}
//兵部打仗
private void fight(){
System.out.println("兵部:我只出人,剩下的找別人幹去。");
super.department.selfFunction();
super.ministry.selfFunction();
}
//工部建行宮
private void buildPalace(){
System.out.println("工部:我只畫圖紙,其他的找別人幹去。");
super.department.selfFunction();
super.defense.selfFunction();
}
}
複製程式碼
③抽象部門類
public abstract class AbstractColleague {
protected AbstractMediator abstractMediator;
public AbstractColleague(AbstractMediator abstractMediator) {
this.abstractMediator = abstractMediator;
}
}
複製程式碼
④戶部
public class Department extends AbstractColleague{
public Department(AbstractMediator abstractMediator) {
super(abstractMediator);
}
public void dealDisaster(){
super.abstractMediator.dealThing(Mediator.DEPARTMENT_CODE);
}
public void selfFunction(){
System.out.println("要錢沒問題,我儘量搜刮點民脂民膏。");
}
}
複製程式碼
⑤兵部
public class Defense extends AbstractColleague{
public Defense(AbstractMediator abstractMediator) {
super(abstractMediator);
}
public void fight(){
super.abstractMediator.dealThing(Mediator.MINISTRY_CODE);
}
public void selfFunction(){
System.out.println("兵部:要人沒問題,我儘量抓多幾個壯丁");
}
}
複製程式碼
⑥工部
public class Ministry extends AbstractColleague{
public Ministry(AbstractMediator abstractMediator) {
super(abstractMediator);
}
public void buildPalace(){
super.abstractMediator.dealThing(Mediator.MINISTRY_CODE);
}
public void selfFunction(){
System.out.println("要建築圖紙沒問題,我儘量複製多幾份");
}
}
複製程式碼
⑦Client
public class Client {
public static void main(String[] args) {
AbstractMediator abstractMediator=new Mediator();
//發生天災了,戶部麻煩了,需要解決問題
Department department=new Department(abstractMediator);
department.dealDisaster();
//要打仗了,兵部的活來了
Defense defense=new Defense(abstractMediator);
defense.fight();
//皇帝發話了,工部趕緊建行宮
Ministry ministry=new Ministry(abstractMediator);
ministry.buildPalace();
}
}
複製程式碼
輸出的結果為:
//發生天災了,戶部麻煩了,需要解決問題
戶部:專挑輕活,其他的找別人幹去。
工部:要建築圖紙沒問題,我儘量複製多幾份。
兵部:要人沒問題,我儘量抓多幾個壯丁。
//要打仗了,兵部的活來了
兵部:我只出人,剩下的找別人幹去。
戶部:要錢沒問題,我儘量搜刮點民脂民膏。
工部:要建築圖紙沒問題,我儘量複製多幾份。
//皇帝發話了,工部趕緊建行宮
工部:我只畫圖紙,其他的找別人幹去。
戶部:要錢沒問題,我儘量搜刮點民脂民膏。
兵部:要人沒問題,我儘量抓多幾個壯丁。
複製程式碼