本文實(shí)例代碼:https://github.com/JamesZBL/java_design_patterns
中介者(Mediator)模式是用來降低多個對象和類之間的通信復(fù)雜性的。這種模式中通常提供一個充當(dāng)中介者角色的類,用來承擔(dān)“中心化”或“集中化”的職能,與各個對象之間都可以分別相互通信,它的一大優(yōu)勢是減少或避免其他對象之間的互相通信,在通信方面降低了耦合度。
實(shí)例
現(xiàn)在要舉行一場派對,派對中會穿插各種游戲活動,凡是參加派對的人都要到派對舉辦者那里登記。并且,每次有參與者想要參加派對中的某個活動的時候都要先向派對舉辦者提出請求,由舉辦者來批準(zhǔn)他的請求,然后這個活動才開始進(jìn)行。
先定義派對舉辦者行為的接口,舉辦者的職責(zé)有邀請成員加入和批準(zhǔn)成員參加活動
Party.java
public interface Party {
void addMember(PartyMember member);
void letAct(PartyMember member, Activity activity);
}
然后是派對成員的接口,成員的職責(zé)有參加派對、提出參加活動的請求以及參加活動
PartyMember.java
public interface PartyMember {
void joinParty(Party party);
void partyActivity(Activity activity);
void act(Activity activity);
}
再定義一個類來具體實(shí)現(xiàn)派對舉辦者功能
PartyImpl.java
public class PartyImpl implements Party {
private List<PartyMember> members;
public PartyImpl() {
members = new ArrayList<>();
}
@Override
public void addMember(PartyMember member) {
members.add(member);
member.joinParty(this);
}
@Override
public void letAct(PartyMember member, Activity activity) {
for (PartyMember m : members) {
if (!member.equals(m)) {
m.partyActivity(activity);
}
}
}
}
定義一個派對實(shí)現(xiàn)成員接口的抽象類,保留一個 toString() 抽象方法,留到其具體子類中實(shí)現(xiàn)
AbstractPartyMember.java
public abstract class AbstractPartyMember implements PartyMember {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPartyMember.class);
private Party party;
@Override
public void joinParty(Party party) {
LOGGER.info("{}加入了派對", this);
this.party = party;
}
@Override
public void act(Activity activity) {
if (null != activity) {
LOGGER.info("{}提議進(jìn)行{}活動", this, activity);
party.letAct(this, activity);
}
}
@Override
public void partyActivity(Activity activity) {
LOGGER.info("進(jìn)行派對活動,名稱:{},介紹:{}", activity, activity.getDescription());
}
@Override
public abstract String toString();
}
派對中提供的活動有射擊、猜燈謎、桌游和唱歌,為其定義一個枚舉類
Activity.java
public enum Activity {
SHOOT("射擊", "Shooting"), GUESS("猜燈謎", "Guess"), DESKTOP_GAME("桌游", "Desktop games"), SING("唱歌", "singing");
private String name;
private String description;
Activity(String name, String description) {
this.name = name;
this.description = description;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return name;
}
}
有四種不同職業(yè)或特點(diǎn)的參與者,分別繼承自 AbstractPartyMember 類,分別覆蓋了父類中的 toString() 方法來表示其特征
他們分別是 Officer.java,Oldman.java,Student.java 和 Businessman.java,此處省略具體代碼
現(xiàn)在來舉辦一次派對,參與者們分別向派對舉辦者提出活動請求,舉辦者分別批準(zhǔn)
App.java
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
// 派對舉辦者
Party party = new PartyImpl();
// 學(xué)生
Student student = new Student();
// 官員
Officer officer = new Officer();
// 商人
Businessman businessman = new Businessman();
// 老人
Oldman oldman = new Oldman();
// 邀請成員加入
party.addMember(student);
party.addMember(officer);
party.addMember(businessman);
party.addMember(oldman);
// 分別提出參加活動的請求
student.act(Activity.DESKTOP_GAME);
officer.act(Activity.GUESS);
businessman.act(Activity.SHOOT);
oldman.act(Activity.SING);
}
}
總結(jié)
需要使用中介者模式的場景是對象與對象之間存在大量的關(guān)聯(lián)關(guān)系,這樣下去會導(dǎo)致系統(tǒng)的結(jié)構(gòu)變得復(fù)雜,一個對象的改動勢必會影響到另一個與之關(guān)聯(lián)的對象,,同時做出相應(yīng)的改動,它們之間分別相互耦合,幾乎形成了“網(wǎng)狀”的結(jié)構(gòu),這對于復(fù)雜的系統(tǒng)是非常不利的。
中介者模式可以將這種 “網(wǎng)狀結(jié)構(gòu)” 解耦形成 “星形結(jié)構(gòu)”,最典型的應(yīng)用實(shí)例就是 MVC 結(jié)構(gòu),其中的 C (控制器) 就擔(dān)當(dāng)了 V(視圖)和 M(模型)之間的中介者。
中介者模式的缺點(diǎn)是會使中介者對象異常復(fù)雜,降低了可維護(hù)性,所以應(yīng)當(dāng)盡量避免在對象間的職責(zé)劃分比較難以界定的場景中使用。
個人博客同步更新,獲取更多技術(shù)分享請關(guān)注:鄭保樂的博客