淺談Mediator仲裁者模式

1、前言java

Mediator模式又稱爲仲裁者模式或中介者模式,所起的做用就是仲裁和中介,幫助其它類之間進行交流。在仲裁者模式之中,咱們要明確兩個概念,那就是仲裁者(Mediator)和組員(Colleague),無論組員有什麼事情,都會向仲裁者彙報,仲裁者會根據全局的實際狀況向其餘Colleague做出指示,共同完成必定的邏輯功能。編程

2、代碼設計模式

Mediator接口:(仲裁者接口)ide

package designMode.mediator;

public interface Mediator {
    public abstract void createColleagues();
    public abstract void ColleagueChanged();
}

 Colleague 組員接口:函數

package designMode.mediator;

public interface Colleague {
    public abstract void setMediator(Mediator mediator);
    public abstract void setColleagueEnable(boolean enable);
}

ColleagueButton實現類:組件化

package designMode.mediator;

import java.awt.*;

public class ColleagueButton extends Button implements Colleague {
    private static final long serialVersionUID = 1309335015058337931L;
    public ColleagueButton(String caption){
        super(caption);
    }

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

    @Override
    public void setColleagueEnable(boolean enable) {
        setEnabled(enable);
    }
}

ColleagueCheckBox實現類:this

package designMode.mediator;

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

public class ColleagueCheckBox extends Checkbox implements ItemListener,Colleague {
    private static final long serialVersionUID = -628547709974079324L;
    public ColleagueCheckBox(String caption,CheckboxGroup g,boolean b){
        super(caption,g,b);
    }
    private Mediator mediator;
    @Override
    public void setMediator(Mediator mediator) {
        this.mediator=mediator;
    }

    @Override
    public void setColleagueEnable(boolean enable) {
        setEnabled(enable);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        mediator.ColleagueChanged();
    }
}

ColleagueTextField實現類spa

package designMode.mediator;

import java.awt.*;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;

public class ColleagueTextField extends TextField implements TextListener,Colleague {
    private static final long serialVersionUID = 8539124564669846422L;
    public ColleagueTextField(String text,int columns){
        super(text,columns);
    }
    private Mediator mediator;
    @Override
    public void setMediator(Mediator mediator) {
        this.mediator=mediator;
    }

    @Override
    public void setColleagueEnable(boolean enable) {
        setEnabled(enable);
        setBackground( enable? Color.WHITE : Color.BLACK );
    }

    @Override
    public void textValueChanged(TextEvent e) {
        mediator.ColleagueChanged();
    }
}

LoginFrame實現類.net

package designMode.mediator;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class LoginFrame extends Frame implements ActionListener, Mediator {
    private static final long serialVersionUID = -509490729876024682L;

    private ColleagueButton buttonOK;
    private ColleagueButton buttonCancel;

    private ColleagueCheckBox chkGuest;
    private ColleagueCheckBox chkUser;

    private ColleagueTextField tfUser;
    private ColleagueTextField tfPass;

    public LoginFrame(String title){
        super(title);
        setBackground(Color.lightGray);
        setLayout(new GridLayout(4,2));
        createColleagues();
        add(chkGuest);
        add(chkUser);
        add(new Label("用戶名:"));
        add(tfUser);
        add(new Label("密碼:"));
        add(tfPass);
        add(buttonOK);
        add(buttonCancel);
        ColleagueChanged();
        pack();
        show();
    }

    public void createColleagues() {
        CheckboxGroup chk=new CheckboxGroup();
        chkGuest=new ColleagueCheckBox("Guest",chk,true);
        chkUser=new ColleagueCheckBox("User",chk,false);
        buttonOK=new ColleagueButton("OK");
        buttonCancel=new ColleagueButton("Cancel");
        tfUser=new ColleagueTextField("",10);
        tfPass=new ColleagueTextField("",10);
        tfPass.setEchoChar('#');

        chkGuest.setMediator(this);
        chkUser.setMediator(this);
        buttonOK.setMediator(this);
        buttonCancel.setMediator(this);
        tfUser.setMediator(this);
        tfPass.setMediator(this);

        chkGuest.addItemListener(chkGuest);
        chkUser.addItemListener(chkUser);
        buttonOK.addActionListener(this);
        buttonCancel.addActionListener(this);
        tfUser.addTextListener(tfUser);
        tfPass.addTextListener(tfPass);

    }

    public void ColleagueChanged() {

        if(chkGuest.getState()){
            tfUser.setColleagueEnable(false);
            tfPass.setColleagueEnable(false);
            buttonOK.setColleagueEnable(true);
        }else{
            tfUser.setColleagueEnable(true);
            userPassChanged();
        }
    }

    private void userPassChanged() {
        if(tfUser.getText().length()>0){
            tfPass.setColleagueEnable(true);
            if(tfPass.getText().length()>0){
                buttonOK.setColleagueEnable(true);
            }else{
                buttonOK.setColleagueEnable(false);
            }
        }else{
            tfPass.setColleagueEnable(false);
            buttonOK.setColleagueEnable(false);
        }

    }

    public void actionPerformed(ActionEvent e) {
        System.out.println(e.toString());
        System.exit(0);
    }
}

Main方法設計

package designMode.mediator;

public class Main {
    public static void main(String[] args) {
        LoginFrame login = new LoginFrame("仲裁者模式");
    }
}

運行結果

遊客訪問,不用輸入用戶名和密碼,所以禁用。

會員訪問,只有輸入用戶名以後才能輸入密碼,用戶名可用,密碼暫不能用,登陸按鈕OK不可用。

會員訪問,輸入用戶名和密碼以後,登陸按鈕OK可用。

點擊登陸按鈕OK:

分析:這些組件(按鈕、文本框、單選框)每個發生改變以後就要致使其餘組件發生改變,好比用戶名文本框改變,密碼文本框也要響應改變,若是咱們直接讓這兩個文本框之間產生交互,咱們應該怎樣寫代碼呢?咱們可能在用戶名文本框發生改變的函數中通知密碼文本框,讓密碼文本框可用,那麼咱們須要獲得密碼文本框的對象,這一定是一件很是難以作到的事情,一樣的,密碼文本框的改變還要使得按鈕發生改變,咱們勢必會將密碼文本框和按鈕之間再次創建聯繫(傳遞參數),這也是一件很是複雜的事情,一樣的單選框發生改變,兩個文本框和一個按鈕都要發生改變,這又要在單選框之中獲得這些組件的對象,而後才能改變這些組件的狀態,可是單選框都有兩個,來自於同一個類,咱們要怎麼識別呢,可能還要經過必定的方法獲得單選框的ID,這是極其複雜的,最讓人難以接受的是,若是需求發生了改變,好比又增長了一個控件,剩餘的全部組件的代碼都要修改,而這些代碼之間本就混亂無比,再次修改就更讓人難以接受了,所以這不是一個好的辦法,甚至能夠說是一個很是差的解決辦法。

那麼有什麼好的解決辦法嗎?那就是將這些複雜的邏輯操做獨立出來,新建立一個類,在每一個空間的狀態發生改變的時候就能經過某種方式通知這個類,讓這個類改變這些控件的狀態,這樣說來這個新的類應該持有這些控件的引用,這樣才能委託這些控件去改變本身的狀態,同時這些控件要想通知這個新的類,那就要持有這個類的引用,這樣才能委託新的類去實現全部狀態的改變。這樣咱們的思路就清晰明瞭了,若是一個再增長一個新的控件,須要添加邏輯,咱們只須要修改仲裁者的方法,就能夠作到全局的掌控,達到了修改最少的代碼來擴展程序的行爲,所以仲裁者模式很是的重要和實用。

3、總結

對咱們的程序而言,仲裁者模式適合於某一個部分發生改變就會致使其餘部分做出相應的改變的狀況,咱們將這種變換的規律抽象出來,編程仲裁者,從而很好地協商各個部分,當組員有問題的時候,直接告訴仲裁者,不與其它成員打交道,讓仲裁者賦值這些繁瑣的事務,這樣條理就很清晰了,所以仲裁者也成爲中介者,能夠想象不少人要去租房,不少人要把房子出租,若是私下裏面去商量,既浪費時間,又很難找到對方,經過中介這個對象,它收集了不少的租房和出租房的信息,這樣就能很快的找到最適合的房子。因而可知生活就是最好的設計模式。仲裁者模式對於代碼的修改(很容易定位錯誤)、新的成員的加入、代碼的複用(組員部分能夠複用,仲裁者部分不易複用)都有着必定的簡化,將該集中處理的集中起來,將該分散的分散出去,無疑是一種好的設計模式。對比於外觀模式Facade,仲裁者須要和組員溝通,是雙向的,而外觀模式facade角色只是對其餘角色進行整合,是單向的。設計模式至今咱們已經研究了16種了,這其中不少設計模式都是有着關聯的,一樣也有着不一樣之處,可是都和實際問題是分不開的,設計模式是實際問題的抽象和解決方法,爲了提升可擴展性和組件化,實際問題是設計模式的來源和最終歸宿。

 

淺談設計模式<最通俗易懂的講解>

相關文章
相關標籤/搜索