中介者模式——调停者

来源:互联网 发布:tensorflow参数微调 编辑:程序博客网 时间:2024/05/14 21:49

(《设计模式解析与实战——何红辉,关爱民》读书笔记)

一、定义
中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散耦合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。中介者模式将多对多的相互作用转化为一对多的相互作用。中介者模式将对象的行为 和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
比如,一个做App的公司大体可以分为运维、产品、开发、设计和测试,这几个部门平时肯定会有意见不合的地方,这时总经理或者老板就需要权衡利弊,使损失最小,这时总经理或者老板的角色就是充当中介者角色。

二、使用场景
当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其他对象的行为,可采用中介者模式,来解决紧耦合问题。该模式将对象之间的多对多关系变成一对多关系,中介者对象将系统从网状结构变成以调停者为中心的星形结构,达到降低系统的复杂性,提高可扩展性的作用。

三、中介者模式的通用模式代码

/** * 抽象中介者:定义了同事对象到中介者对象的接口,一般以抽象类的方法实现 */public abstract class Mediator {    // 具体同事类A    protected ConcreteColleagueA conlleagueA;    // 具体同事类B    protected ConcreteColleagueB conlleagueB;    // 抽象中介方法、子类实现    public abstract void method();    public void setConlleagueA(ConcreteColleagueA conlleagueA) {        this.conlleagueA = conlleagueA;    }    public void setConlleagueB(ConcreteColleagueB conlleagueB) {        this.conlleagueB = conlleagueB;    }}
package com.mediator.model;/** * 具体中介者:实现父类定义的方法,它从具体的的同事对象接收消息,向具体同事对象发出命令 */public class ConcreteMediator extends Mediator{    @Override    public void method() {        conlleagueA.action();        conlleagueB.action();    }}
package com.mediator.model;/** * 抽象同事:定义了中介者对象的接口,它只知道中介者而不知道其他的同事对象 */public abstract class Colleague {    // 中介者对象    protected Mediator mediator;    public Colleague(Mediator mediator) {        this.mediator = mediator;    }    /**     * 同事角色的具体行为,由子类去实现     */    public abstract void action();}
package com.mediator.model;/** * 具体同事A:每个具体同事类都知道本身在小范围内的行为,而不知道他在大范围内的目的 */public class ConcreteColleagueA extends Colleague {    public ConcreteColleagueA(Mediator mediator) {        super(mediator);    }    @Override    public void action() {        System.out.println("ColleagueA 将信息递交给中介者处理");    }}
package com.mediator.model;/** * 具体同事B:每个具体同事类都知道本身在小范围内的行为,而不知道他在大范围内的目的 */public class ConcreteColleagueB extends Colleague {    public ConcreteColleagueB(Mediator mediator) {        super(mediator);    }    @Override    public void action() {        System.out.println("ColleagueB 将信息递交给中介者处理");    }}

四、中介者模式在Android中的应用
比如,一个登陆界面通常包含两个文本框、两个按钮、两个复选框。
业务需求:
(1)用户名没有输入时除了取消按钮外均不可用;
(2)密码没有输入,除了文本框,记住账户复选框和取消按钮外其余均不可用,当且仅当账户密码均正确时所有空间才可用;
(3)如果勾选了自动登录,记住账户也会自动勾选,并且账户密码不可编辑;
(4)自动登录取消,勾选记住账户,会置空密码框。
当然平常我们不会去套用中介者模式框架,大多数情况下我们直接让Activity来充当一个中介者并在其中处理相关的逻辑。

布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <LinearLayout        android:id="@+id/ll_layout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="100dp"        android:orientation="vertical">        <EditText            android:id="@+id/et_name"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_margin="5dp"            android:hint="账户" />        <EditText            android:id="@+id/et_password"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_margin="5dp"            android:hint="密码"            android:password="true" />    </LinearLayout>    <RelativeLayout        android:id="@+id/rl_layout1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/ll_layout"        android:layout_marginTop="20dp"        android:orientation="horizontal">        <CheckBox            android:id="@+id/cb_remeber"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="5dp"            android:text="记住账户" />        <CheckBox            android:id="@+id/cb_auto"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_marginRight="5dp"            android:text="自动登录" />    </RelativeLayout>    <RelativeLayout        android:id="@+id/rl_layout2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/rl_layout1"        android:layout_marginTop="20dp">        <Button            android:id="@+id/btn_ok"            android:layout_width="100dp"            android:layout_height="wrap_content"            android:layout_marginLeft="5dp"            android:text="确定" />        <Button            android:id="@+id/btn_cancle"            android:layout_width="100dp"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_marginRight="5dp"            android:text="取消" />    </RelativeLayout></RelativeLayout>

这里写图片描述

import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.Editable;import android.text.TextUtils;import android.text.TextWatcher;import android.view.View;import android.widget.Button;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.EditText;import android.widget.Toast;public class LoginActivity extends AppCompatActivity {    private EditText mEtAccount, mEtPassword;    private Button mBtnOK, mBtnCancle;    private CheckBox mCbRemember, mCbAuto;    // 账户文本,密码文本    private String mStrAccount, mStrPassword;    // 是否记住账户,是否自动登录    private boolean isRemember, isAuto;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_login);        // 初始化View        initViews();        // 监听账户文本改变        textAccountWatch();        // 监听密码文本改变        textPasswordWatch();        // 监听确定按钮事件        btnOKListener();        // 监听取消按钮事件        btnCancleListener();        // 监听自动登录复选框        cbAutoListener();        // 监听记住账户复选框        cbRememberListener();    }    private void cbRememberListener() {        mCbRemember.setEnabled(false);        mCbRemember.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                // 回传数据                isRemember = isChecked;                // 通知Activity状态改变                change();            }        });    }    private void cbAutoListener() {        mCbAuto.setEnabled(false);        mCbAuto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                // 回传数据                isAuto = isChecked;                // 通知Activity状态改变                change();            }        });    }    private void btnCancleListener() {        mBtnCancle.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(LoginActivity.this, "Login cancle!", Toast.LENGTH_SHORT).show();            }        });    }    private void btnOKListener() {        mBtnOK.setEnabled(false);        mBtnOK.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(LoginActivity.this, "Login success!", Toast.LENGTH_SHORT).show();            }        });    }    private void textPasswordWatch() {        mEtPassword.setEnabled(false);        mEtPassword.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                // 回传数据                mStrPassword = s.toString();                // 通知Activity状态改变                change();            }            @Override            public void afterTextChanged(Editable s) {            }        });    }    private void textAccountWatch() {        mEtAccount.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                // 回传数据                mStrAccount = s.toString();                // 通知Activity状态改变                change();            }            @Override            public void afterTextChanged(Editable s) {            }        });    }    private void initViews() {        mEtAccount = (EditText) findViewById(R.id.et_account);        mEtPassword = (EditText) findViewById(R.id.et_password);        mBtnOK = (Button) findViewById(R.id.btn_ok);        mBtnCancle = (Button) findViewById(R.id.btn_cancle);        mCbRemember = (CheckBox) findViewById(R.id.cb_remember);        mCbAuto = (CheckBox) findViewById(R.id.cb_auto);    }    /**     * 各控件状态改变后协调各控件状态显示     */    private void change() {        // 账户为空        if (TextUtils.isEmpty(mStrAccount)) {            mEtPassword.setEnabled(false);            mCbRemember.setEnabled(false);            mCbAuto.setEnabled(false);            mBtnOK.setEnabled(false);            mBtnCancle.setEnabled(true);            // 账户不空,密码为空        } else if (!TextUtils.isEmpty(mStrAccount) && TextUtils.isEmpty(mStrPassword)) {            mEtPassword.setEnabled(true);            mCbAuto.setEnabled(false);            mCbRemember.setEnabled(true);            mBtnOK.setEnabled(false);            mBtnCancle.setEnabled(true);            // 账户不空,密码不空        } else if (!TextUtils.isEmpty(mStrAccount) && !TextUtils.isEmpty(mStrPassword)) {            mEtPassword.setEnabled(true);            mCbRemember.setEnabled(true);            mCbAuto.setEnabled(true);            mBtnOK.setEnabled(true);            mBtnCancle.setEnabled(true);        }    }}

Activity目录结构:
这里写图片描述

这里写图片描述

五、总结
在面向对象的编程语言里,一个类必然会与其他类产生依赖关系,如果这种依赖关系如网状般错综复杂,那么必然会影响我们的代码逻辑以及执行效率,适当的使用中介者模式可以对这种依赖关系进行解耦使逻辑结构清晰;
但是,如果及各类间的依赖关系并不复杂,使用中介者模式反而会使得原本不复杂的逻辑结构变得复杂。
所以,我们在决定使用中介者模式之前要多方考虑、权衡利弊。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 头撞墙起包了怎么办 儿童头撞墙起包怎么办 头撞墙了鼓包了怎么办 北京65岁老年证怎么办 怎么办65岁免费乘车卡 5个月小孩晚上哭怎么办 婴儿要含奶头睡怎么办 我把输入法删了怎么办 头发干枯毛躁怎么办用什么洗发水 落枕后脖子歪了怎么办 睡觉睡得脖子疼怎么办? 婴儿脖子睡歪了怎么办 怀孕8个月肚皮痒怎么办 怀孕大阴唇肿了怎么办 孕妇肚皮撑的疼怎么办 我大阴唇特别长怎么办 切完洋葱辣眼睛怎么办 下昆山车没刷卡怎么办 高德地图用不了怎么办 玩游戏老是闪退怎么办 苹果平板电脑闪退怎么办 钉钉忘记打卡了怎么办 钉钉手机号换了怎么办 玖富叮当贷逾期怎么办 玖富超能怎么办现金贷 包包的油边开裂怎么办 lv包包油边开裂怎么办 lv钱包油边开裂怎么办 德运奶粉没勺子怎么办 音响坏了没声音怎么办 6s蓝牙无法配对怎么办 魅族耳机进水了怎么办 苹果6耳机进水了怎么办 耳机内部线坏了怎么办 酷狗m1开不开机怎么办 小米2s蓝牙坏了怎么办 苹果手机蓝牙坏了怎么办 老婆不精明傻笨怎么办 老婆管得太严怎么办 骂自己父母的人怎么办 5岁宝宝说谎话怎么办