Mediator pattern is to help package a serious of objects inside of mediator class when they have complicated connection relationships, rather than we give logic control under each object itself.
When we extend more objects in the project, we only make amendment in mediator class, no need to touch other objects class, but indeed, this pattern doesn't fulfill OCP.
Take an complicated example, like we have several roles related to one house, landlord, tenant, agency and the bank.
1. If landlord sells the house, tenant must leave the house, agency needs to find the house buyer, bank will receive prepaid loan;
2. If tenant wants to stop renting the house, agency will look for new tenat, landload will stop receiving the rent until agency finds the new tenant;
3. Agent company collapses, landlord will need to find a new agency;
4. Bank withdraws loan request, landlord may sell the house and pay the loan, tenant needs to move out and rent another house, agency will look for house buyer.
So we maintain the logic in mediator class, rather than put different logic inside of each participant.
- Colleague
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public abstract class Colleague {
Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void action();
}
Landlord / Tenant / Agency / Bank
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class Landlord extends Colleague{
public Landlord(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
this.mediator.getAction(this);
}
public void sellHouse(){
System.out.println("Landlord will sell his house soon...");
}
public void stopReceiveRent(){
System.out.println("Landlord will not receive the rent until there's new tenant...");
}
public void findNewAgency(){
System.out.println("Landlord will need to find new agency...");
}
}
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class Tenant extends Colleague{
public Tenant(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
this.mediator.getAction(this);
}
public void stopRent() {
System.out.println("Tenant will stop renting the house soon...");
}
public void moveOut() {
System.out.println("Tenant needs to move out the house and find a new place...");
}
}
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class Agency extends Colleague{
public Agency(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
this.mediator.getAction(this);
}
public void collapse(){
System.out.println("Agent company collapses...");
}
public void findNewBuyer(){
System.out.println("Agency will find a new house buyer...");
}
public void findNewTenant(){
System.out.println("Agent will find a new house tenant...");
}
}
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class Bank extends Colleague{
public Bank(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
this.mediator.getAction(this);
}
public void withdrawLoanRequest(){
System.out.println("Bank will withdraw previous landlord’s loan request...");
}
public void receivePrepayment(){
System.out.println("Bank will receive loan prepayment...");
}
}
Mediator / Concrete Mediator
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public abstract class Mediator {
Map<String, Colleague> colleagueMap;
public abstract void register(String name, Colleague colleague);
public abstract void getAction(Colleague colleague);
public abstract void responseAction(Colleague colleague);
}
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class HouseMediator extends Mediator {
public HouseMediator() {
this.colleagueMap = new HashMap<String, Colleague>();
}
@Override
public void register(String name, Colleague colleague) {
this.colleagueMap.put(name, colleague);
}
@Override
public void getAction(Colleague colleague) {
if (Landlord.class.equals(colleague.getClass())) {
((Landlord) colleagueMap.get("landlord")).sellHouse();
} else if (Tenant.class.equals(colleague.getClass())) {
((Tenant) colleagueMap.get("tenant")).stopRent();
} else if (Agency.class.equals(colleague.getClass())) {
((Agency) colleagueMap.get("agency")).collapse();
} else if (Bank.class.equals(colleague.getClass())) {
((Bank) colleagueMap.get("bank")).withdrawLoanRequest();
}
}
@Override
public void responseAction(Colleague colleague) {
if (Landlord.class.equals(colleague.getClass())) {
((Tenant) colleagueMap.get("tenant")).moveOut();
((Agency) colleagueMap.get("agency")).findNewBuyer();
((Bank) colleagueMap.get("bank")).receivePrepayment();
} else if (Tenant.class.equals(colleague.getClass())) {
((Landlord) colleagueMap.get("landlord")).stopReceiveRent();
((Agency) colleagueMap.get("agency")).findNewTenant();
} else if (Agency.class.equals(colleague.getClass())) {
((Landlord) colleagueMap.get("landlord")).findNewAgency();
} else if (Bank.class.equals(colleague.getClass())) {
((Landlord) colleagueMap.get("landlord")).sellHouse();
((Tenant) colleagueMap.get("tenant")).moveOut();
((Agency) colleagueMap.get("agency")).findNewBuyer();
}
}
}
Client side,
/**
* @Author Carter Deng
* @Date 2021/11/24
*/
public class Test {
public static void main(String[] args) {
HouseMediator mediator = new HouseMediator();
Colleague landlord = new Landlord(mediator);
Colleague tenant = new Tenant(mediator);
Colleague agency = new Agency(mediator);
Colleague bank = new Bank(mediator);
mediator.register("landlord", landlord);
mediator.register("tenant", tenant);
mediator.register("agency", agency);
mediator.register("bank", bank);
System.out.println("==========landlord===========");
landlord.action();
mediator.responseAction(landlord);
System.out.println("");
System.out.println("==========tenant===========");
tenant.action();
mediator.responseAction(tenant);
System.out.println("");
System.out.println("==========agency===========");
agency.action();
mediator.responseAction(agency);
System.out.println("");
System.out.println("==========bank===========");
bank.action();
mediator.responseAction(bank);
System.out.println("");
}
}
Output result:
==========landlord===========
Landlord will sell his house soon...
Tenant needs to move out the house and find a new place...
Agency will find a new house buyer...
Bank will receive loan prepayment...
==========tenant===========
Tenant will stop renting the house soon...
Landlord will not receive the rent until there's new tenant...
Agent will find a new house tenant...
==========agency===========
Agent company collapses...
Landlord will need to find new agency...
==========bank===========
Bank will withdraw previous landlord’s loan request...
Landlord will sell his house soon...
Tenant needs to move out the house and find a new place...
Agency will find a new house buyer...
It's easy to extend colleague items, but needs to update concrete mediator class logic.