小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(); }}复制代码
输出的结果为:
//发生天灾了,户部麻烦了,需要解决问题户部:专挑轻活,其他的找别人干去。工部:要建筑图纸没问题,我尽量复制多几份。兵部:要人没问题,我尽量抓多几个壮丁。//要打仗了,兵部的活来了兵部:我只出人,剩下的找别人干去。户部:要钱没问题,我尽量搜刮点民脂民膏。工部:要建筑图纸没问题,我尽量复制多几份。//皇帝发话了,工部赶紧建行宫工部:我只画图纸,其他的找别人干去。户部:要钱没问题,我尽量搜刮点民脂民膏。兵部:要人没问题,我尽量抓多几个壮丁。复制代码