設計模式學習筆記(十七)中介者模式及其應用場景
中介者(Mediator)模式:定義了一個單獨的中介對象,來封裝一組對象之間的交互。將這組對象之間的交互委派給與中介對象交互,來避免對象之間的直接交互。比如我們各種設備之間的通訊,就是通過伺服器作為中介對象來進行交互:
一、中介者模式介紹
中介者又叫做調停模式,是一種對象行為型模式,它降低了對象之間的耦合性,讓對象易於被獨立地調用,是迪米特法則的典型應用,下面就來看看中介者模式的結構和實現:
1.1 中介者模式的結構
中介者模式主要通過引入用於協調其他對象或類之間相互調用的中介者類,為了讓系統具有具有更好的靈活性和擴展性。其結構如下圖所示:
上面的類圖中主要包含以下角色:
Mediator
:抽象中介者,是中介者的介面/抽象類ConcreteMeditor
:中介者的具體實現,實現中介者介面,定義一個List來管理Colleague
對象Colleague
:抽象同事類,定義同事類的介面/抽象類,保存中介者對象,實現同事類的公共方法ConcreteColleague1、ConcreteColleague2
:具體同事類,實現抽象同事類。通過中介者間接完成具體同事類之間的通訊交互
1.2 中介者模式的實現
根據上面的類圖,可以實現如下程式碼:
- 抽象中介者及其實現
/**
* @description: 中介者抽象類
* @author: wjw
* @date: 2022/4/7
*/
public abstract class Mediator {
/**註冊同事類*/
public abstract void register(Colleague colleague);
/**處理接收邏輯*/
public abstract void operation(Colleague colleague);
}
/**
* @description: 具體中介者類
* @author: wjw
* @date: 2022/4/7
*/
public class ConcreteMediator extends Mediator{
private List<Colleague> colleagues = new ArrayList<Colleague>();
@Override
public void register(Colleague colleague) {
if (!colleagues.contains(colleague)) {
colleagues.add(colleague);
colleague.setMediator(this);
}
}
@Override
public void operation(Colleague colleague) {
for (Colleague coll : colleagues) {
if (!coll.equals(colleague)) {
coll.receive();
}
}
}
}
- 抽象同事類及其實現
/**
* @description: 抽象同事類
* @author: wjw
* @date: 2022/4/7
*/
public abstract class Colleague {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
/**
* @description: 具體同事類1
* @author: wjw
* @date: 2022/4/7
*/
public class ConcreteColleague1 extends Colleague{
@Override
public void receive() {
System.out.println("具體同事類 ConcreteColleague1 接收請求");
}
@Override
public void send() {
System.out.println("具體同事類 ConcreteColleague1 發送請求");
/*中介者進行轉發*/
mediator.operation(this);
}
}
/**
* @description: 具體同事類2
* @author: wjw
* @date: 2022/4/7
*/
public class ConcreteColleague2 extends Colleague{
@Override
public void receive() {
System.out.println("具體同事類 ConcreteColleague2 接收到請求");
}
@Override
public void send() {
System.out.println("具體同事類 ConcreteColleague2 發送請求");
mediator.operation(this);
}
}
- 客戶端測試類
/**
* @description: 客戶端
* @author: wjw
* @date: 2022/4/7
*/
public class Client {
public static void main(String[] args) {
Mediator concreteMediator = new ConcreteMediator();
Colleague concreteColleague1 = new ConcreteColleague1();
Colleague concreteColleague2 = new ConcreteColleague2();
concreteMediator.register(concreteColleague1);
concreteMediator.register(concreteColleague2);
concreteColleague1.send();
concreteColleague2.send();
}
}
測試結果為:
具體同事類 ConcreteColleague1 發送請求
具體同事類 ConcreteColleague2 接收到請求
具體同事類 ConcreteColleague2 發送請求
具體同事類 ConcreteColleague1 接收請求
二、中介者模式應用場景
2.1 中介者模式的適用情況
如果遇到以下情況可以考慮使用中介者模式:
- 系統中對象之間存在複雜的引用關係,系統結構混亂且難以理解
- 一個對象由於引用了其他很多對象並且直接和這些對象通訊,導致難以復用該對象
- 需要通過一個中間類來封裝多個類中的行為,但又不想生成太多的子類
2.2 中介者模式在MVC模式中的應用
比如說,在MVC框架中,控制器(Controller)就是模型(Model)和視圖(View)之間的中介者:
- Model(模型):代表一個存取對象的數據,有Dao、Bean等等
- View(視圖):表示所看到的東西,比如網頁、JSP等用於展示模型中的數據
- Controller(控制器):作用於模型和視圖中間,控制數據流向模型對象,在數據變化時更新視圖
三、中介者模式實戰
3.1 ORM框架
我們知道在Java與資料庫交互中JDBC可以完成對多種資料庫操作,舉一個利用JDBC查詢的例子:
//1.載入MySQL驅動注入到DriverManager
Class.forName("com.mysql.cj.jdbc.Driver");
//2.提供JDBC連接的URL、用戶名和密碼
String url = "jdbc:mysql://localhost:3306/test_db?";
String username = "root";
String password = "root";
//3.創建資料庫的連接
Connection connection = DriverManager.getConnection(url, username, password);
//4.創建statement實例
Statement statement = connection.createStatement();
//5.1執行SQL語句,得到ResultSet對象,
String query = "select * from test"; //查詢語句,也可以換成CRUD的其他語句
ResultSet resultSet = statement.executeQuery(query);
while(resultSet.next()){
//5.2通過ResultSet讀取數據後,將數據轉換成JavaBean對象
}
//6.關閉連接對象
connection.close();
在上面的步驟中,步驟1~4和6都可以封裝重複執行,但是在第5步中,需要完成關係模型ResultSet
到對象模型JavaBean
的轉換,而這一部分使用通用的方式封裝這種複雜的轉換是比較困難的,因此有ORM(Object Relational Mapping, 對象-關係映射)框架來解決對象轉換關係模型的映射問題。同時也屏蔽了之前JDBC連接中的重複程式碼,只提供簡單的API供開發人員進行使用。
3.2 利用中介者模式模仿MyBatis核心功能
在本案例中我們通過模仿MyBatis 中核心ORM框架功能,來使用中介者模式。首先來看看ORM框架在資料庫和應用交互中的位置:
從圖中可以看出,ORM框架位於資料庫層和應用層中間,相當於兩者之間的中介。在實際MyBatis 實現過程中,不僅用到了中介者模式,還有工廠模式和建造者模式。
在ORM框架實現的核心類中,包括載入配置文件、對XML進行解析、獲取資料庫session、操作資料庫以及返回結果等步驟。在ORM內部的結構如下圖所示(來自《重學Java設計模式》):
- 左上框內是對資料庫的定義和處理,包括
<T> T selectOne
、<T> List<T> selectList
等等 - 右上是對資料庫配置的開啟session的工廠處理類,工廠會操作
DefaultSqlSession
- 最後是核心類
SqlSessionFactoryBuilder
,它可以實現處理工廠、解析文件、拿session等操作
下面就來看看具體程式碼
實戰程式碼
- 創建對應資料庫、JavaBean和Dao介面
創建資料庫design-mediatro
,數據表user
和school
參考資料
《重學Java設計模式》
《Java設計模式》
《MyBatis技術內幕》
//c.biancheng.net/view/1393.html