终结者模式

Java 设计模式 之 中介者模式(Mediator)

2011-07-03 18:43:14|  分类: Java 设计模式 |  标签:java  设计模  中介者模式  mediator  |举报|字号 订阅

中介者的功能非常简单,就是封装对象之间的交互

如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把所有麻烦扔给它,只要在需要的时候通知中介者,其他的就让中介者去处理就可以了。

反过来,其他对象在操作时,可能会引起这个对象的变化,也可以这么做。最后对象之间就完全分离了,谁都不直接跟其他对象交互,那么相互之间的关系完全集中到中介者里面了,所有的对象都通过中介者进行通信,相互之间就不在有联系了,对象之间的耦合就松散了。

● 标准的中介者模式

① Mediator :中介者接口。在里面定义各个同事对象之间的交互对象,可以是公共的通信方法,比如changed 方法,大家都用,也可以是小范围的交互方法。

② ConcreteMediator :具体中介者实现对象。他需要维护各个同事对象之间的交互关系,比如下例中的MainBoard。

③ Colleague :同事类的定义,所有具体同事类的父类,通常实现成抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的功能。

④ ConcreteColleague :具体的同事类,实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者负责与其他的同事进行交互。

/**
 * 中介者,定义各个同事对象的通信接口
 * @author joe
 *
 */
public interface Mediator {

/**
           * 同事对象在自身改变的时候来通知中介者的方法
           * 让中介者去负责相应的与其他同事对象的交互
           * @param colleague 同事对象自身,好让中介者对象通过对象实例
           * 去获取同事对象的状态
           */
         public void changed(Colleague colleague);
}

/**
 * 主板类,实现中介者接口
 *
 */
public class MainBoard implements Mediator {

private CDDriver cdDriver;
          private CPU cpu;
          private VideoCard videoCard;
          private SoundCard soundCard;
 
          @Override
         public void changed(Colleague colleague) {
                  if(colleague == cdDriver){
                          //表示光驱读取了数据
                          this.operateCDDriverReadData((CDDriver)colleague);
                  }else if(colleague == cpu){
                         //表示CPU处理完数据
                         this.operateCPU((CPU)colleague);
                  }
         }

public void setCdDriver(CDDriver cdDriver) {
                   this.cdDriver = cdDriver;
         }

public void setCpu(CPU cpu) {
                  this.cpu = cpu;
         }

 public void setVideoCard(VideoCard videoCard) {
                 this.videoCard = videoCard;
         }

 public void setSoundCard(SoundCard soundCard) {
                 this.soundCard = soundCard;
         }
         /**
          * 处理光驱读取数据后与其他对象的交互
          * @param cd
          */
        public void operateCDDriverReadData(CDDriver cd){
                 String data = cd.getData();
                 this.cpu.executeData(data);
        }
        /**
         * 处理CPU处理完数据后与其他对象的交互
         * @param cpu
         */
        public void operateCPU(CPU cpu){
                  String videoData = cpu.getVideoData();
                  String soundData = cpu.getSoundData();
                  this.videoCard.showData(videoData);
                  this.soundCard.soundData(soundData);
        }
}

/**
 * 同事类的抽象父类
 *
 */
public abstract class Colleague {
         /**
          * 持有中介者对象,每一个同事类都知道它的中介者对象
          */
         private final Mediator mediator;
         /**
          * 构造方法,传入中介者对象
          * @param mediator 中介者对象
          */
        public Colleague(Mediator mediator){
                  this.mediator = mediator;
        }
        /**
         * 获得当前同事类对应的中介者对象
         * @return 对应的中介者对象
         */
        public Mediator getMediator(){
                 return mediator;
        }
}

/**
 * 光驱类,一个同事类
 *
 */
public class CDDriver extends Colleague {

/**
           * 光盘数据
           */
         private String data;
 
         public CDDriver(Mediator mediator) {
                   super(mediator);
         }
         /**
          * 获取光盘读取出来的数据
          * @return 光盘数据
          */
         public String getData() {
                  return data;
         }
         /**
          * 读取光盘
          */
         public void readCD(){
                   //逗号前是视频数据,逗号后是音频数据
                  this.data = "Video Data,Sound Data";
                 //通知主板,自己的状态发生了变化
                  this.getMediator().changed(this);
         }
}

/**
 * CPU 类,一个同事类
 *
 */
public class CPU extends Colleague {
          /**
           * 视频数据
           */
         private String videoData;
         /**
          * 音频数据
          */
         private String soundData;
 
         public CPU(Mediator mediator) {
                   super(mediator);
         }

public String getVideoData() {
                    return videoData;
         }

public String getSoundData() {
                    return soundData;
         }
         /**
          * 处理数据,把数据分解成视频数据和音频数据
          * @param data 被处理的数据
          */
        public void executeData(String data){
                 //分解数据,前面是视频数据,后面是音频数据
                 String[] ss = data.split(",");
                 this.videoData = ss[0];
                 this.soundData = ss[1];
                 //通知主板,CPU的工作完成
                 this.getMediator().changed(this);
        }
}

/**
 * 声卡类,一个同事类
 *
 */
public class SoundCard extends Colleague {

public SoundCard(Mediator mediator){
                    super(mediator);
           }
           /**
            * 发出声音
            * @param data 音频数据
            */
           public void soundData(String data){
                    System.out.println("画外音:" + data);
           }
}

/**
 * 显卡类,一个同事类
 *
 */
public class VideoCard extends Colleague {

public VideoCard(Mediator mediator) {
                    super(mediator);
          }
          /**
           * 显示视频数据
           * @param data 被显示的数据
           */
          public void showData(String data){
                    System.out.println("你正在观看的是:" + data);
          }
}

public class Client {

  public static void main(String[] args) {
                    MainBoard mediator = new MainBoard();
                    CDDriver cd = new CDDriver(mediator);
                    CPU cpu = new CPU(mediator);
                    VideoCard vc = new VideoCard(mediator);
                    SoundCard sc = new SoundCard(mediator);
  
                    mediator.setCdDriver(cd);
                    mediator.setCpu(cpu);
                    mediator.setVideoCard(vc);
                    mediator.setSoundCard(sc);
   
                    cd.readCD();
           }
}

● 广义中介者

① 通常会去掉同事对象的父类,这样可以让任意的对象,只要需要相互交互,就可以成为同事。

② 同事不定义Mediator 接口,把具体的中介者实现成单例

③ 同事对象不再持有中介者对象,而是在具体处理方法里面去创建,或者获取,或者从参数传入需要的同事对象。

/**
 * 描述部门与人员关系的类
 *
 */
public class DepUserModel {

private String depUserId;
          private String depId;
          private String userId;

//省略Setter 和 Getter

}

/**
 * 实现部门和人员交互的中介者实现类
 *
 */
public class DepUserMediatorImpl {

private static DepUserMediatorImpl mediator = new DepUserMediatorImpl();
 
           private DepUserMediatorImpl(){
                      initTestData();
           }
 
           public static DepUserMediatorImpl getInstance(){
                     return mediator;
           }
           /**
            * 记录部门和人员关系
            */
           private final Collection<DepUserModel> depUserCol = new ArrayList<DepUserModel>();
             /**
              * 初始化测试数据
              */
            private void initTestData(){
                        DepUserModel du1 = new DepUserModel();
                        du1.setDepUserId("du1");
                        du1.setDepId("d1");
                        du1.setUserId("u1");
                        depUserCol.add(du1);
  
                        DepUserModel du2 = new DepUserModel();
                        du2.setDepUserId("du2");
                        du2.setDepId("d1");
                        du2.setUserId("u2");
                        depUserCol.add(du2);
  
                        DepUserModel du3 = new DepUserModel();
                        du3.setDepUserId("du3");
                        du3.setDepId("d2");
                        du3.setUserId("u3");
                        depUserCol.add(du3);
  
                        DepUserModel du4 = new DepUserModel();
                        du4.setDepUserId("du4");
                        du4.setDepId("d2");
                        du4.setUserId("u4");
                        depUserCol.add(du4);
  
                        DepUserModel du5 = new DepUserModel();
                        du5.setDepUserId("du5");
                        du5.setDepId("d2");
                        du5.setUserId("u1");
                        depUserCol.add(du5);
            }
            /**
             * 当部门被撤销时,应删去部门与该部门中人员的关系
             * @param depId 被撤销部门的编号
             * @return
             */
            public boolean deleteDep(String depId){
                      Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
                      for(DepUserModel du : depUserCol){
                                 if(du.getDepId().equals(depId)){
                                              tempCol.add(du);
                                 }
                      }
                      depUserCol.removeAll(tempCol);
                      return true;
            }
            /**
             * 当人员离职时,应删去该人员与所在部门的关系
             * @param userId 离职人员的编号
             * @return
             */
           public boolean deleteUser(String userId){
                     Collection<DepUserModel> tempCol = new ArrayList<DepUserModel>();
                     for(DepUserModel du : depUserCol){
                                 if(du.getUserId().equals(userId)){
                                             tempCol.add(du);
                                 }
                      }
                     depUserCol.removeAll(tempCol);
                     return true;
          }
          /**
           * 显示部门中的所有人员
           * @param dep 部门对象
           */
          public void showDepUser(Dep dep){
                    for(DepUserModel du : depUserCol){
                              if(du.getDepId().equals(dep.getDepId())){
                                        System.out.println("部门编号=" + dep.getDepId() + "下面拥有人员,其编号是:" + du.getUserId());
                              }
                      }
         }
         /**
          * 显示人员所在的部门
          * @param user 人员对象
          */
         public void showUserDeps(User user){
                   for(DepUserModel du : depUserCol){
                            if(du.getUserId().equals(user.getUserId())){
                                        System.out.println("人员编号=" + user.getUserId() + "属于部门编号是:" + du.getDepId());
                            }
                    }
        }
        /**
         * 完成因人员调换部门引起的与部门的交互
         * @param userId 被调换的人员的编号
         * @param oldDepId 调换前的部门编号
         * @param newDepId 调换后的部门编号
         * @return
         */
        public boolean changeDep(String userId, String oldDepId, String newDepId){
                  // 本示例就不是实现了
                  return false;
        }
        /**
         * 因部门合并所引起的与人员的交互
         * @param colDepIds 需要被合并的部门编号
         * @param newDep 合并后部门的编号
         * @return
         */
        public boolean joinDep(Collection<String> colDepIds, Dep newDep){
                  // 本示例就不是实现了
                  return false;
        }
}

public class User {

private String userId;
          private String userName;

/**
           * 人员离职
           * @return
           */
          public boolean dimission(){
                    DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
                    mediator.deleteUser(userId);
                    return true;
         }

//省略Getter 和 Setter
}

/**
 * 部门类
 *
 */
public class Dep {

private String depId;
          private String depName;

/**
           * 撤销部门
           * @return
           */
          public boolean deleteDep(){
                    DepUserMediatorImpl  mediator = DepUserMediatorImpl.getInstance();
                    mediator.deleteDep(depId);
                    return true;
          }
}

public class Client {

public static void main(String[] args) {
                    DepUserMediatorImpl mediator = DepUserMediatorImpl.getInstance();
  
                    Dep dep = new Dep();
                    dep.setDepId("d1");
                    Dep dep2 = new Dep();
                    dep2.setDepId("d2");
  
                    User user = new User();
                    user.setUserId("u1");
  
                    System.out.println("撤销部门前----------------------------------------");
                    mediator.showUserDeps(user);
                    //撤销部门
                    dep.deleteDep();
                    System.out.println("撤销部门后----------------------------------------");
                    mediator.showUserDeps(user);
  
                    System.out.println("----------------------------------------");
                    System.out.println("人员离职前----------------------------------------");
                    mediator.showDepUser(dep2);
                    //人员离职
                    user.dimission();
                    System.out.println("人员离职后----------------------------------------");
                    mediator.showDepUser(dep2);
        }
}

时间: 2024-07-29 05:50:02

终结者模式的相关文章

18.设计模式_终结者模式

一.引言 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 二. 中介者模式的介绍 2.1 中介者模式的定义 从生活中的例子可以看出,不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了.电话.短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其

Observer(观察者)模式

1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是出于各种原因,你也许并不愿意因为代码环境的改变而对代码做大的修改.也许,你只想根据你的具体应用环境而改进通信代码.或者,你只想简单的重新构造通信代码来避免类和类之间的相互依赖与相互从属. 2.问题 当一个对象的状态发生改变时,你如何通知其他对象?是否需要一个动态方案――一个就像允许脚本的执行一样,允

设计模式之: 中介者模式

一.前言 平常我们写一个聊天软件,如果我们只是各个客户端之间连接聊天,那估计我们会写的想哭,那如果我们用服务器作为中间媒介,通过服务器来完成转发,群聊等客户端之间的连接,那样我们就可以最大程度的为各个客户端之间解耦,把它们之间的通信方法抽出来单独实现, 如图1就是不使用中介媒体的时候的结构图: 如图2就是使用我们所说的服务器作为中间媒介的情况的结构图: 二.中介模式 图二就是我们所说的中介模式! 在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装

设计模式(25)-----中介者模式

中介者(Mediator) 定义 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. UML图 角色 Mediator:中介者接口.在里面定义了各个同事之间相互交互所需要的方法,可以是公共的方法,如Change方法,也可以是小范围的交互方法. ConcreteMediator:具体的中介者实现对象.它需要了解并为维护每个同事对象,并负责具体的协调各个同事对象的交互关系. Colleague:同事类的定义,通常实现成为抽象

设计模式--14、中介者模式

定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 类型:行为类模式 看看结构图的形象描述吧: 中介者模式的结构 中介者模式又称为调停者模式,从类图中看,共分为3部分: 抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信.一般包括一个或几个抽象的事件方法,并由子类去实现. 中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法.从一个同事类接收消息,然后通过消息影响其他同时类. 同事

php设计模式(二):结构模式

上一篇我们介绍了设计模式的特性并且详细讲解了4种创建型模式,创建型模式是负责如何产生对象实例的,现在我们继续来给大家介绍结构型模式.一.什么是结构型模式? 结构型模式是解析类和对象的内部结构和外部组合,通过优化程序结构解决模块之间的耦合问题. 二.结构型模式的种类:    适配器模式    桥接模式    装饰模式    组合模式    外观模式    享元模式    代理模式 1. 适配器模式(Adapter) 将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能

重温设计模式

设计模式,及软件设计中的"套路".每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题解决方案的核心,这样,你就能一次又一次的使用该方案而不必做重复的劳动.设计模式大约有20多种,它们使人们可以更加简单方便的复用成功的设计和体系结构,提高系统维护的有效性.与设计模式密切相关的是6大设计原则,那么就从这些设计原则开始设计模式重温之旅吧.(ps:内容有点小多) 一.6大设计模式 1.单一职责原则 核心思想:应该有且仅有一个原因引起类的变更 问题描述:假如有类Class1完成职责T1

.NET设计模式简析

首先,是设计模式的分类,我们知道,常用的设计模式共23种.但总体来说,设计模式氛围三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单列模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模版方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.转改模式.访问者模式.终结者模式.解释器模式. 另外还有并发型模式和线程池模式等. 介绍了分类,下面简单说下设计模式的六大原则

4年前阅读《大话设计模式》摘抄的经典语句

前言 在自己的网盘中查找Memcached相关资料时,偶然看到自己很早之前阅读<大话设计模式>时所摘抄的经典语句.阅读完此书之后,对设计模式有了粗浅的认识,跟别人交流也能说道一二.感谢作者无私的分享! 经典语句 1 通过封装.继承.多态把程序的耦合度降低2 用设计模式使得程序更加的灵活,容易修改,并且易于复用3 聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分[DPE]4 合成(Composition,也有翻译成‘组合’的)是一种强的‘拥有’关系,体现了严