中介者模式(Mediator)

1. 定義

用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。java

2.結構

這裏寫圖片描述

  • Mediator:中介者定義一個接口用於與各同事(Colleague)對象通訊。
  • ConcreteMediator:具體中介者經過協調各同事對象實現協做行爲,瞭解並維護它的各個同事。
  • Colleague:抽象同事類。
  • ConcreteColleague:具體同事類。每一個具體同事類都只須要知道本身的行爲便可,可是他們都須要認識中介者。

3. 實例

咱們使用一個例子來講明一下什麼是同事類:有兩個類A和B,類中各有一個數字,而且要保證類B中的數字永遠是類A中數字的100倍。也就是說,當修改類A的數時,將這個數字乘以100賦給類B,而修改類B時,要將數除以100賦給類A。類A類B互相影響,就稱爲同事類。
不使用中介者的實現:git

AbstractColleaguegithub

/** * @author lijun * @since 2018-04-09 9:37 */
public abstract class AbstractColleague {
    protected int number;    

    public int getNumber() {    
        return number;    
    }    

    public void setNumber(int number){    
        this.number = number;    
    }
    /** * 抽象方法,修改數字時同時修改關聯對象 */
    public abstract void setNumber(int number, AbstractColleague coll);
}

ConcreteColleagueA編程

/** * @author lijun * @since 2018-04-09 9:37 */
public class ConcreteColleagueA extends AbstractColleague{
    @Override
    public void setNumber(int number, AbstractColleague coll) {
        this.number = number;    
        coll.setNumber(number*100);    
    }    
}

ConcreteColleagueBruby

/** * @author lijun * @since 2018-04-09 9:37 */
public class ConcreteColleagueB extends AbstractColleague{

    @Override
    public void setNumber(int number, AbstractColleague coll) {
        this.number = number;    
        coll.setNumber(number/100);    
    }    
}

Clientide

public class Client {
    public static void main(String[] args){    

        AbstractColleague collA = new ConcreteColleagueA();
        AbstractColleague collB = new ConcreteColleagueB();

        System.out.println("==========設置A影響B==========");    
        collA.setNumber(1288, collB);    
        System.out.println("collA的number值:"+collA.getNumber());    
        System.out.println("collB的number值:"+collB.getNumber());    

        System.out.println("==========設置B影響A==========");    
        collB.setNumber(87635, collA);    
        System.out.println("collB的number值:"+collB.getNumber());    
        System.out.println("collA的number值:"+collA.getNumber());    
    }    
}

輸出this

==========設置A影響B========== collA的number值:1288
collB的number值:128800
==========設置B影響A========== collB的number值:87635
collA的number值:876

上面的代碼中,類A類B經過直接的關聯發生關係,假如咱們要使用中介者模式,類A類B之間則不能夠直接關聯,他們之間必需要經過一箇中介者來達到關聯的目的。spa

Mediator 中介者接口code

/** * 中介者接口 * @author lijun * @since 2018-04-09 9:34 */
public interface Mediator {

    /** *影響A */
    public void  affectA();

    /** * */
    public void  affectB();
}

ConcreteMediator 具體的中介者對象

/** * 具體的中介者 * * @author lijun * @since 2018-04-09 9:37 */
public class ConcreteMediator implements Mediator {

    /** * 中介者持有同事類A */
    ConcreteColleagueA  concreteColleagueA;

    /** * 中介者持有同類B */
    ConcreteColleagueB concreteColleagueB;


    public void setConcreteColleagueA(ConcreteColleagueA concreteColleagueA) {
        this.concreteColleagueA = concreteColleagueA;
    }

    public void setConcreteColleagueB(ConcreteColleagueB concreteColleagueB) {
        this.concreteColleagueB = concreteColleagueB;
    }

    /** * 影響A */
    @Override
    public void affectA() {
        concreteColleagueA.setNumber(concreteColleagueB.getNumber()/100);
    }

    /** * */
    @Override
    public void affectB() {
        concreteColleagueB.setNumber(concreteColleagueA.getNumber()*100);
    }
}

AbstractColleague 同事抽象類

/** * 同事抽象類 * @author lijun * @since 2018-04-09 9:34 */
public abstract class AbstractColleague {
    protected int number;
    private Mediator mediator;

    public AbstractColleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Mediator getMediator() {
        return mediator;
    }

    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    /** * 設置number的值 * * @param number 值 * @param mediator 中介者 */
    public abstract void setNumber(int number, Mediator mediator);

}

ConcreteColleagueA 同事類A

/** * 同事類A 設置同事類A的值影響B的值 * 經過中介者來改變B的值 * * @author lijun * @since 2018-04-09 9:42 */
public class ConcreteColleagueA extends AbstractColleague {

    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }
    /** * 設置number的值 * * @param number 值 * @param mediator 中介者 */
    @Override
    public void setNumber(int number, Mediator mediator) {
        this.number = number;
        mediator.affectB();
    }
}

ConcreteColleagueB 同事類B

/** * 同事類B 設置同事類B的值影響B的值 * 經過中介者來改變A的值 * * @author lijun * @since 2018-04-09 9:42 */
public class ConcreteColleagueB extends AbstractColleague {

    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }

    /** * 設置number的值 * * @param number 值 * @param mediator 中介者 */
    @Override
    public void setNumber(int number, Mediator mediator) {
        this.number = number;
        mediator.affectA();
    }
}

Client

public class Client {
    public static void main(String[] args) {

        //中介者
        ConcreteMediator mediator = new ConcreteMediator();

        //同事對象
        ConcreteColleagueA concreteColleagueA = new ConcreteColleagueA(mediator);
        ConcreteColleagueB concreteColleagueB = new ConcreteColleagueB(mediator);

        //中介者設置同事對象
        mediator.setConcreteColleagueA(concreteColleagueA);
        mediator.setConcreteColleagueB(concreteColleagueB);

        System.out.println( "==========設置A影響B==========");
        concreteColleagueA.setNumber(100, mediator);
        System.out.println("concreteColleagueA: "+concreteColleagueA.getNumber());
        System.out.println("concreteColleagueB: "+concreteColleagueB.getNumber());

        System.out.println( "==========設置B影響A==========");
        concreteColleagueB.setNumber(1000, mediator);

        System.out.println("concreteColleagueB: "+concreteColleagueB.getNumber());
        System.out.println("concreteColleagueA: "+concreteColleagueA.getNumber());

    }
}

輸出:

==========設置A影響B========== concreteColleagueA: 100
concreteColleagueB: 10000
==========設置B影響A========== concreteColleagueB: 1000
concreteColleagueA: 10

4. 本質

封裝交互

5.優缺點和總結

1.優勢

  • 適當地使用中介者模式能夠避免同事類之間的過分耦合,使得各同事類之間能夠相對獨立地使用。
  • 使用中介者模式能夠將對象間一對多的關聯轉變爲一對一的關聯,使對象間的關係易於理解和維護。
  • 使用中介者模式能夠將對象的行爲和協做進行抽象,可以比較靈活的處理對象間的相互做用。

2.缺點

  • 過分集中化。若是同事對象的交互很是多,而已比較複雜,當這個複雜性所有集中到中介者的時候,會致使中介者對象變得十分複雜,並且難以管理和維護。

3.總結

在面向對象編程中,一個類必然會與其餘的類發生依賴關係,徹底獨立的類是沒有意義的。一個類同時依賴多個類的狀況也至關廣泛,既然存在這樣的狀況,說明,一對多的依賴關係有它的合理性,適當的使用中介者模式可使本來凌亂的對象關係清晰,可是若是濫用,則可能會帶來反的效果。通常來講,只有對於那種同事類之間是網狀結構的關係,纔會考慮使用中介者模式。能夠將網狀結構變爲星狀結構,使同事類之間的關係變的清晰一些。中介者模式是一種比較經常使用的模式,也是一種比較容易被濫用的模式。對於大多數的狀況,同事類之間的關係不會複雜到混亂不堪的網狀結構,所以,大多數狀況下,將對象間的依賴關係封裝的同事類內部就能夠的,沒有必要非引入中介者模式。濫用中介者模式,只會讓事情變的更復雜。

源碼地址

相關文章
相關標籤/搜索