博文原址:折騰Java設(shè)計模式之中介者模式
公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計、成都做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)建站是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出阿拉善盟免費做網(wǎng)站回饋大家。
中介者模式(Mediator Pattern)是用來降低多個對象和類之間的通信復(fù)雜性。這種模式提供了一個中介類,該類通常處理不同類之間的通信,并支持松耦合,使代碼易于維護。中介者模式屬于行為型模式。
通俗點來講就是提供一個中介平臺,說到平臺,那其實很容易聯(lián)系到我們很熟悉的房地產(chǎn)中介。我們可以直接通過這個平臺得到我們想要的信息,不用對象自身與其他對象交互。
買房子租房子就不需要去找房東,只需要在中介那里獲取相應(yīng)的×××信息。如下圖那樣,兩方只需要找中介即可。
cdn.xitu.io/2019/4/11/16a09f7d3a72b202?w=500&h=391&f=jpeg&s=22358">
再來看一張對比圖。
有沒有感覺沒有使用之前,對象間互相依賴互相調(diào)用,錯綜復(fù)雜,盤根錯節(jié),當(dāng)加入中介者后,對象間的關(guān)系一目了然,清晰明了。由中介對象來封裝一系列對象之間的交互關(guān)系。中介者使各個對象之間不需要顯式地相互引用,從而使耦合性降低,而且可以獨立地改變它們之間的交互行為。
collague1和collague2類不直接相互依賴,它們是用起控制和協(xié)調(diào)交互作用的公共中介接口(mediate()方法),這使它們有獨立交互的執(zhí)行方式。mediate1類實現(xiàn)collague1和collague2之間的依賴。
抽象中介者(Mediator): 定義了同事對象到中介者對象之間的接口。
具體中介者(ConcreteMediator): 實現(xiàn)抽象中介者的方法,它需要知道所有的具體同事類,同時需要從具體的同事類那里接收信息,并且向具體的同事類發(fā)送信息。
抽象同事類(Colleague): 定義了中介者對象的接口,它只知道中介者而不知道其他的同事對象。
具體同事類(ConcreteColleague) : 每個具體同事類都只需要知道自己的行為即可,但是他們都需要認識中介者。
源碼地址
抽象中介者
@Slf4j
public abstract class Mediator {
/**
* 房東map
*/
protected Map landlordMap = Maps.newHashMap();
/**
* 租戶列表
*/
protected List renterList = Lists.newArrayList();
/**
* 注冊房東信息
*
* @param landlord 房東
* @param message 房屋信息
*/
public void registerLandlord(People landlord, Message message) {
landlordMap.put(landlord, message);
log.info("中介信息:房東|{}|加入到中介平臺,房屋信息:{}", landlord.getName(), message);
}
/**
* 變更房東信息
*
* @param landlord 房東
* @param message 房屋信息
*/
protected void modifyLandlordInfo(People landlord, Message message) {
landlordMap.put(landlord, message);
log.info("中介信息:房東|{}|修改他在中介平臺的房屋信息,現(xiàn)房屋信息:{}", landlord.getName(), message);
}
/**
* 注冊租戶信息
*
* @param renter 租戶
*/
public void registerRenter(People renter) {
renterList.add(renter);
log.info("中介信息:租戶|{}|來中介平臺租房", renter.getName());
}
/**
* 聲明抽象方法 由具體中介者子類實現(xiàn) 消息的中轉(zhuǎn)和協(xié)調(diào)
*/
public abstract void operation(People people, Message message);
}
抽象同事類
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class People {
private Mediator mediator;
private String name;
/**
* 向中介發(fā)送消息
*/
protected abstract void sendMessage(Message message);
/**
* 從中介獲取消息
*/
protected abstract void getMessage(Message message);
}
具體同事類 房東和租戶
@Slf4j
public class Landlord extends People {
public Landlord(Mediator mediator, String name) {
super(mediator, name);
}
@Override
protected void sendMessage(Message message) {
getMediator().operation(this, message);
}
@Override
protected void getMessage(Message message) {
log.info("房東|{}|從中介獲取到租戶的信息:{}", getName(), message);
}
}
@Slf4j
public class Renter extends People {
public Renter(Mediator mediator, String name) {
super(mediator, name);
}
@Override
protected void sendMessage(Message message) {
getMediator().operation(this, message);
}
@Override
protected void getMessage(Message message) {
log.info("租戶|{}|從中介獲取到房東的信息:{}", getName(), message);
}
}
具體中介者
public class RealEstateAgent extends Mediator {
@Override
public void operation(People people, Message message) {
if (people instanceof Renter) {
// 將租戶的租房條件信息發(fā)送給房東們
landlordMap.keySet().forEach(landlord -> landlord.getMessage(message));
// 租戶收到中介那里房東的房屋信息
landlordMap.values().forEach(messages -> people.getMessage(messages));
} else if (people instanceof Landlord) {
// 將房東的房屋信息發(fā)送給租戶們
renterList.forEach(renter -> renter.getMessage(message));
// 變更中介里的房東房屋信息
modifyLandlordInfo(people, message);
}
}
}
客戶端
@Slf4j
public class Client {
public static void main(String[] args) {
Mediator mediator = new RealEstateAgent();
People laoWang = new Landlord(mediator, "老王");
People laoLee = new Landlord(mediator, "老李");
People laoBai = new Landlord(mediator, "老白");
People xiaoSan = new Renter(mediator, "小3");
People xiaoWang = new Renter(mediator, "小王");
mediator.registerLandlord(laoWang, Message.builder().msg("我這有2500的房子,市中心").build());
mediator.registerLandlord(laoBai, Message.builder().msg("我這有2000的房子,地鐵旁").build());
mediator.registerLandlord(laoLee, Message.builder().msg("我這有2000的房子,落地陽臺,大空間,采光好,地鐵旁").build());
mediator.registerRenter(xiaoSan);
log.info("小3開始找房子");
xiaoSan.sendMessage(Message.builder().msg("想找個月租2000塊的房子,靠近地鐵").build());
log.info("沒過多久---------老白升級了房屋信息");
laoBai.sendMessage(Message.builder().msg("我這有2000的房子,地鐵旁,我又加了空調(diào)和熱水器").build());
mediator.registerRenter(xiaoWang);
log.info("小王開始找房子");
xiaoWang.sendMessage(Message.builder().msg("想找個月租2500塊的房子,靠近地鐵").build());
log.info("沒過多久---------老李也升級了房屋信息");
laoBai.sendMessage(Message.builder().msg("我這有2000的房子,落地陽臺,大空間,采光好,地鐵旁,我也加了空調(diào)和熱水器").build());
}
}
最終出效果的如下
現(xiàn)在我來分析下里面各個角色的作用:
首先先分析兩個抽象類。抽象同事類,含有名稱和中介者的引用,有2個方法從中介拿信息和發(fā)信息給中介。抽象中介者,其中含有房東的map信息,key為房東數(shù)據(jù),value為房東的房屋信息,用來房東注冊和房東房屋信息變更;租戶的列表信息,供租戶注冊,同時還有個協(xié)調(diào)方法,用于協(xié)調(diào)房東和租戶。
具體抽象類(房地產(chǎn)中介),實現(xiàn)了抽象中介者的協(xié)調(diào)方法,當(dāng)租戶發(fā)送消息時,將租戶的租房條件信息發(fā)送給所有房東們同時該租戶收到中介那里所有房東的房屋信息;當(dāng)房東發(fā)送消息時,將房東的房屋信息發(fā)送給所有租戶們同時變更中介里的改房東房屋信息。
具體同事實現(xiàn)類(房東和租戶),實現(xiàn)了抽象同事類的讀取消息方法和發(fā)送消息方法(該房屋就是依靠中介者的協(xié)調(diào)方法來實現(xiàn))。
通過使用一個中間對象來進行消息分發(fā)以及減少類之間的直接依賴。
java.util.Timer
java.util.concurrent.Executor#execute()
java.util.concurrent.ExecutorService#submit()
java.lang.reflect.Method#invoke()
使用中介者模式可以把對個同事對象之間的交互封裝到中介者對象里面,從而使得同事對象之間松散耦合。
中介者模式可以將原先多對多的同事對象關(guān)系變成中介者對象一對多同事對象的關(guān)系,這樣會讓對象之間的關(guān)系更容易理解和實現(xiàn)。
同事對象之間的交互都被封裝到中介者對象里面集中管理,集中了控制交互。當(dāng)交互發(fā)生改變時,著重修改的是中介者對象。當(dāng)需要擴展中介者對象時,其他同事對象不需要做修改。
如果同事對象多了,交互也復(fù)雜了。中介者會龐大,變得復(fù)雜難以維護。
中介者模式|菜鳥教程
Mediator pattern
細數(shù)JDK里的設(shè)計模式
JAVA設(shè)計模式之 中介者模式【Mediator Pattern】
歡迎關(guān)注