Location>code7788 >text

Design patterns of the intermediary pattern (three minutes to learn a design pattern)

Popularity:904 ℃/2024-09-24 19:05:04

The Mediator model (Mediator) is also called the mediation model.
mediator [ˈmiːdieɪtə(r)]
n. mediator; good offices; a person (or body) who settles disputes; intended to be an intermediary in the settlement of disputes.
It is a typical application of the principle of least known of the six object-oriented principles.
(For the six object-oriented principles, see the previous article: /jilodream/p/)
The general idea is to design classes with as little coupling to the outside world as possible, with as few dependencies on other classes as possible, which reduces the risk of later modifications to the class.
The official definition is as follows:A mediator object is used to encapsulate a series of object interactions. The mediator object removes the need for each of the other objects to display references to each other. It makes the overall coupling looser, and allows you to change their interactions independently.

It is one of the 23 object-oriented design patterns and belongs to the scope of behavioral patterns.
The intermediary model is roughly like this, for example, if you go to buy a house, whether it's a price discussion or the quality of the house, it's all done through an intermediary, and even though the intermediary packages some logic, the buyer doesn't need to manage all of the seller's information, and retains the seller's contact information. The seller does not have to manage the buyer's information and keep the buyer's contact information. Even though they are buying and selling a home, the buyer and seller interact with each other through the agent and do not communicate directly. The advantage of this is that both buyers and sellers are relieved of the workload of memorizing each other's particulars, which is left to the agent to maintain.
For example, when there is no mediator object added, we A/B both sides need to maintain about m*n dependencies, and if both sides still have to depend on each other, then it is 2*m*n dependencies, and the situation gets more and more complicated when there are more and more instances of A/B.
When we add the mediator object, then we only need to maintain the dependencies between A/B and the mediator object, about 2(m+n) dependencies, (anti-theft link: this article was first published from /jilodream/ )

The difference is probably something like this

direct coupling

Organized through intermediaries

Some people will say AB objects I just call each other, do I need to make it so complicated?

If just a simple call, of course, there is no need to introduce the intermediary class, of course, how simple how to, but if the business future (or already) rely on very complex, should be introduced as early as possible intermediary class, to reduce unnecessary coupling between classes.

Let's look at an example where both sides of the call are
Banks and businesses, they can send messages to each other. We organize the overall structure through an intermediary model:

Bank interface:

 1 package ;
 2 
 3 /**
 4  * @discription
 5  */
 6 public interface Bank {
 7     void sendMsg(String msg);
 8 
 9     void receiveMsg(String msg);
10 
11     void register(UnionPay unionPay);
12 }

Industrial and Commercial Bank of China Realization

 1 package ;
 2 
 3 import .slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class ICBCBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         ("ICBC sends message to business:" + msg);
16         (msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         ("ICBC receives corporate message:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

Construction Bank Realization

 1 package ;
 2 
 3 import .slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class CCBBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         ("Construction Bank sends message to business:" + msg);
16         (msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         ("Construction Bank receives corporate message:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

enterprise interface

1 package ;
2 
3 public interface Company {
4     void sendMsg(String msg);
5 
6     void receiveMsg(String msg);
7 
8     void register(UnionPay unionPay);
9 }

Thousand Degrees, Inc.

 1 package ;
 2 
 3 import .slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class QianDuCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         ("Thousand Degrees sends message to bank:" + msg);
15         (msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         ("Thousand Degrees receives bank message:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

Rice Company

 1 package ;
 2 
 3 import .slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class DaMiCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         ("Rice sends message to bank:" + msg);
15         (msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         ("Rice receives bank message:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

intermediary category

 1 package ;
 2 
 3 import ;
 4 
 5 import ;
 6 
 7 /**
 8  * @discription
 9  */
10 public class UnionPay {
11     private List<Bank> bankList = ();
12 
13     private List<Company> companyList = ();
14 
15     public void register(Object... components) {
16         for (Object component : components) {
17             if (component instanceof Company) {
18                 Company company = (Company) component;
19                 (company);
20                 (this);
21             }
22             if (component instanceof Bank) {
23                 Bank bank = (Bank) component;
24                 (bank);
25                 (this);
26             }
27         }
28     }
29 
30     public void sendBank(String msg) {
31         for (Bank bank : bankList) {
32             (msg);
33         }
34     }
35 
36     public void sendCompany(String msg) {
37         for (Company company : companyList) {
38             (msg);
39         }
40     }
41 }

main category

 1 package ;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class PatternMain {
 7     public static void main(String[] args) {
 8         Bank ccbBank = new CCBBank();
 9         Bank icbcBank = new ICBCBank();
10         Company qianDuCompany = new QianDuCompany();
11         Company daMiCompany = new DaMiCompany();
12         UnionPay unionPay = new UnionPay();
13         (ccbBank, icbcBank, qianDuCompany, daMiCompany);
14         ("Welcome, businesses, to the Construction Bank Loan!");
15         ("Welcome all companies to ICBC to discuss cooperation!");
16         ("Which banks currently have low-interest business loans?");
17         ("Which bank currently has a payroll card offer?");
18     }
19 }

After running the main class, the effect is as follows:

18:58:03.965 [main] WARN  - Construction Bank sends a message to businesses: Welcome to the construction bank loan for all businesses!
18:58:03.969 [main] WARN  - Chidu received a message from the bank: welcome all enterprises to take out loans from the Construction Bank!
18:58:03.969 [main] WARN  - The Rice Company received a message from the bank: all companies are welcome to take out a loan from the Construction Bank!
18:58:03.970 [main] WARN  - ICBC sends message to enterprises: Welcome to ICBC to discuss cooperation!
18:58:03.970 [main] WARN  - Chidu received a message from the bank: welcome all enterprises to discuss cooperation in ICBC!
18:58:03.970 [main] WARN  - Rice Company received a message from the bank: welcome all enterprises to ICBC to discuss cooperation!
18:58:03.970 [main] WARN  - Rice sends a message to banks: which bank currently has low-interest business loans?
18:58:03.971 [main] WARN  - Construction Bank receives business news: which bank currently has low-interest business loans?
18:58:03.971 [main] WARN  - ICBC receives business news: which bank currently has low-interest business loans?
18:58:03.971 [main] WARN  - Rice sends a message to banks: which bank currently has a payroll card offer?
18:58:03.971 [main] WARN  - Construction Bank receives corporate message: which bank currently has a payroll card offer?
18:58:03.971 [main] WARN  - ICBC receives corporate messages:Which bank currently has a payroll card offer?

The code class diagram is shown below:

We can find from the class diagram, the bank and the enterprise are not directly related, they are directly coupled to the intermediary class, all requests and responses are interacting with the intermediary class (anti-theft connection: this article was first published from /jilodream/ )

The advantage of the mediator pattern is decoupling: we can directly organize third-party provider classes without modifying their code.
The downside is also obvious: the business dependency logic is all abstracted away into the mediator class, which can be overly bloated.