中介者模式java_图解Java设计模式之中介者模式

智能家庭项目

1)智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等

2)主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为 :闹铃响起 - 》咖啡机开始做咖啡 -》窗帘自动落下 -》电视机开始播放

传统方案解决智能家庭管理问题

fa8992368090afee8a70b1fac7b29ad5.png

1)当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂。

2)各个电器对象彼此联系,你中有我,我中有你,不利于松耦合。

3)各个电器对象之间所传递的消息(参数),容易混乱

4)当系统增加一个新的电器对象时,或者执行流程改变时,代码的可维护性、扩展性都不理想。

中介者模式基本介绍

1)中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。

中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

2)中介者模式属于行为型模式,使代码易于维护。

3)比如MVC模式,C(Controller控制器)是M(Model模型)和V(View视图)的中介者,在前后端交互时起到来中间人的作用。

中介者模式的原理类图

8ecd33aa3c58630fdb8732043ca8397d.png

对原理类图的说明 :

1)Mediator 就是抽象中介者,定义类同事对象到中介者对象的接口。

2)Colleague 是抽象同事类。

3)ConcreteMediator 具体的中介者对象,实现抽象方法,他需要知道所有的具体的同事类,即以一个集合来管理HashMap,并接收某个同事对象消息,完成相应的任务。

4)ConcreteColleague 具体的同事类,会有很多,每个同事只知道自己的行为,而不了解其他同事类的行为(方法),但是他们都是依赖中介者对象。

中介者模式 - 智能家庭的操作流程

59b7a86ac38de989e28bd4abd7aae082.png

创建ConcreMediator 对象

创建各个同事类对象,比如 :Alarm、CoffeeMachine、TV

在创建同事类对象的时候,就直接通过构造器,加入到colleagueMap

同事类对象,可以调用sendMessage,最终会去调用ConcreteMediator的getMessage方法

getMessage 会根据接收到的同事对象发出的消息来协调调用其他的同事对象,完成任务

可以看到getMessage 是核心方法,完成相应任务

package com.example.demo.mediator;

public abstract class Mediator {

//将给中介者对象,加入到集合中

public abstract void Register(String colleagueName, Colleague colleague);

//接收消息, 具体的同事对象发出

public abstract void GetMessage(int stateChange, String colleagueName);

public abstract void SendMessage();

}

package com.example.demo.mediator;

public abstract class Colleague {

private Mediator mediator;

public String name;

public Colleague(Mediator mediator, String name) {

this.mediator = mediator;

this.name = name;

}

public Mediator GetMediator() {

return this.mediator;

}

public abstract void SendMessage(int stateChange);

}

package com.example.demo.mediator;

public class Alarm extends Colleague {

public Alarm(Mediator mediator, String name) {

super(mediator, name);

// TODO Auto-generated constructor stub

//在创建 Alarm 同事对象时,将自己放入到 ConcreteMediator 对象中[集合]

mediator.Register(name, this);

}

public void SendAlarm(int stateChange) {

SendMessage(stateChange);

}

@Override

public void SendMessage(int stateChange) {

// TODO Auto-generated method stub

//调用的中介者对象的 getMessage

this.GetMediator().GetMessage(stateChange, this.name);

}

}

package com.example.demo.mediator;

public class CoffeeMachine extends Colleague {

public CoffeeMachine(Mediator mediator, String name) {

super(mediator, name);

// TODO Auto-generated constructor stub

mediator.Register(name, this);

}

@Override

public void SendMessage(int stateChange) {

// TODO Auto-generated method stub

this.GetMediator().GetMessage(stateChange, this.name);

}

public void StartCoffee() {

System.out.println("It's time to startcoffee!");

}

public void FinishCoffee() {

System.out.println("After 5 minutes!");

System.out.println("Coffee is ok!");

SendMessage(0);

}

}

package com.example.demo.mediator;

public class Curtains extends Colleague {

public Curtains(Mediator mediator, String name) {

super(mediator, name);

// TODO Auto-generated constructor stub

mediator.Register(name, this);

}

@Override

public void SendMessage(int stateChange) {

// TODO Auto-generated method stub

this.GetMediator().GetMessage(stateChange, this.name);

}

public void UpCurtains() {

System.out.println("I am holding Up Curtains!");

}

}

package com.example.demo.mediator;

public class TV extends Colleague {

public TV(Mediator mediator, String name) {

super(mediator, name);

// TODO Auto-generated constructor stub

mediator.Register(name, this);

}

@Override

public void SendMessage(int stateChange) {

// TODO Auto-generated method stub

this.GetMediator().GetMessage(stateChange, this.name);

}

public void StartTv() {

// TODO Auto-generated method stub

System.out.println("It's time to StartTv!");

}

public void StopTv() {

// TODO Auto-generated method stub

System.out.println("StopTv!");

}

}

package com.example.demo.mediator;

import java.util.HashMap;

public class ConcreteMediator extends Mediator {

//集合,放入所有的同事对象

private HashMap colleagueMap;

private HashMap interMap;

public ConcreteMediator() {

colleagueMap = new HashMap();

interMap = new HashMap();

}

@Override

public void Register(String colleagueName, Colleague colleague) {

colleagueMap.put(colleagueName, colleague);

// TODO Auto-generated method stub

if (colleague instanceof Alarm) {

interMap.put("Alarm", colleagueName);

} else if (colleague instanceof CoffeeMachine) {

interMap.put("CoffeeMachine", colleagueName);

} else if (colleague instanceof TV) {

interMap.put("TV", colleagueName);

} else if (colleague instanceof Curtains) {

interMap.put("Curtains", colleagueName);

}

}

//具体中介者的核心方法

//1. 根据得到消息,完成对应任务

//2. 中介者在这个方法,协调各个具体的同事对象,完成任务

@Override

public void GetMessage(int stateChange, String colleagueName) {

// TODO Auto-generated method stub

//处理闹钟发出的消息

if (colleagueMap.get(colleagueName) instanceof Alarm) {

if (stateChange == 0) {

((CoffeeMachine) (colleagueMap.get(interMap

.get("CoffeeMachine")))).StartCoffee();

((TV) (colleagueMap.get(interMap.get("TV")))).StartTv();

} else if (stateChange == 1) {

((TV) (colleagueMap.get(interMap.get("TV")))).StopTv();

}

else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {

((Curtains) (colleagueMap.get(interMap.get("Curtains")))).UpCurtains();

}

} else if (colleagueMap.get(colleagueName) instanceof TV) {

//如果 TV 发现消息

} else if (colleagueMap.get(colleagueName) instanceof Curtains) {

//如果是以窗帘发出的消息,这里处理...

}

}

@Override

public void SendMessage() {

// TODO Auto-generated method stub

}

}

package com.example.demo.mediator;

import java.util.HashMap;

public class Client {

public static void main(String[] args) {

// TODO Auto-generated method stub

//创建一个中介者对象

Mediator mediator = new ConcreteMediator();

//创建 Alarm 并且加入到 ConcreteMediator 对象的 HashMap

Alarm alarm = new Alarm(mediator, "alarm");

//创建了 CoffeeMachine 对象,并 且加入到 ConcreteMediator 对象的 HashMap

CoffeeMachine coffeeMachine = new CoffeeMachine(mediator,"coffeeMachine");

//创建 Curtains , 并 且加入到 ConcreteMediator 对象的 HashMap

Curtains curtains = new Curtains(mediator, "curtains");

TV tV = new TV(mediator, "TV");

//让闹钟发出消息

alarm.SendAlarm(0);

coffeeMachine.FinishCoffee();

alarm.SendAlarm(1);

}

}

中介者模式的注意事项和细节

1)多个类相互耦合,会形成网站结构,使用中介者模式将网状结构分离为星型结构,进行解耦。

2)减少类间依赖,降低类耦合,符合迪米特法则。

3)中介者承担类较多的责任,一旦中介者出现了问题,整个系统就会受到影响。

4)如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 自动驾驶线性识别路段

python视觉库 OpenCV:OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。它可以用于图像处理、对象识别、特征提取、图像分割等。 Matplotlib:Matplotlib是一个绘图库,可用于创建高质量的二维图表和绘图。它提供了类似于MATLAB的绘图接口,使用户可以…

【CodeForces - 202A】LLPS (思维,字符串)

题干: This problems actual name, "Lexicographically Largest Palindromic Subsequence" is too long to fit into the page headline. You are given string s consisting of lowercase English letters only. Find its lexicographically largest p…

elementui表格宽度适应内容_elementui表格中的列怎么实现自适应列宽

elementui表格中的列怎么实现自适应列宽发布时间:2020-12-28 14:58:04来源:亿速云阅读:53作者:Leah这期内容当中小编将会给大家带来有关elementui表格中的列怎么实现自适应列宽,文章内容丰富且以专业的角度为大家分析和…

【POJ - 2398】Toy Storage (计算几何,二分找位置,叉积,点和直线的位置关系)

题干: Mom and dad have a problem: their child, Reza, never puts his toys away when he is finished playing with them. They gave Reza a rectangular box to put his toys in. Unfortunately, Reza is rebellious and obeys his parents by simply throwing …

【POJ - 1269 】Intersecting Lines (计算几何,直线间的位置关系)

题干: We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line because they are on top of …

java servlet 转发和重定向_JavaWeb(一)Servlet中乱码解决与转发和重定向的区别

前言前面其实已经把Servlet中所有的内容都介绍完了,这篇讲补充一点乱码和重定向与转发之间的区别!一、request请求参数出现乱码问题1.1、get请求1)乱码示例get请求的参数是在url后面提交过来的,也就是在请求行中。结果:Servlet_de…

【POJ - 3304 】Segments(计算几何,思想转化,直线和线段相交)

题干: Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common. Input Input begins with a…

java调用lingo_使用Lingo增强JMS

虽然activemqjencks的jms轻量级解决方案已经很好地在psa中work了,尤其spring的JmsTemplate使得代码更简单,但是还是存在问题。问题来自暑期做psa的时候,linke突然提出要求,需要MDP返回些处理信息,比如处理结果、异常&a…

jsk Star War (线段树维护区间最小最大值 + 二分)

Description 公元20XX年,人类与外星人之间的大战终于爆发。 现有一个人类军团,由n名士兵组成,第i个士兵的战斗力值对应一个非负整数ai (1 \leq i \leq n1≤i≤n)。 有一天,某个战力爆表的外星人NaN单独向地球人宣战&#xff0c…

java jsp导出pdf文件_JSP页面导出PDF格式文件

JSP页面导出PDF格式文件基本在前端页面可以全部完成添加下载链接的点击事件var downPdf document.getElementById("downLoad");downPdf.onclick function() {downPdf.parentNode.removeChild(downPdf);html2canvas(document.body, {onrendered:function(canvas) {v…

【51Nod - 1094】和为k的连续区间 (前缀和,二分查找)

题干&#xff1a; 一整数数列a1, a2, ... , an&#xff08;有正有负&#xff09;&#xff0c;以及另一个整数k&#xff0c;求一个区间i,ji,j&#xff0c;(1 < i < j < n)&#xff0c;使得aii ... ajj k。 Input 第1行&#xff1a;2个数N,K。N为数列的长度。K为需…

简述java的线程_Java多线程的简述

线程与进程进程&#xff1a;​ 是指一个内存中运行的应用程序&#xff0c;每个进程都有一个独立的内存空间&#xff0c;一个应用程序可以同时运行多个进程&#xff1b;进程也是程序的一次执行过程&#xff0c;是系统运行程序的基本单位&#xff1b;系统运行一个程序即是一个进程…

【POJ - 3253】Fence Repair(贪心,时光倒流)

题干&#xff1a; Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000) planks of wood, each having some integer length Li (1 ≤ Li ≤ 50,000) units. He t…

java unsafe park_Java中Unsafe类详解

http://www.cnblogs.com/mickole/articles/3757278.htmlJava不能直接访问操作系统底层&#xff0c;而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作&#xff0c;主要提供了以下功能&#xff1a;1、通过Unsafe类可以分配内存&#xff0c;可以释放内存&#xff1b;类中…

【CodeForces - 124D】Squares (旋转坐标系,计算几何,思维)

题干&#xff1a; You are given an infinite checkered field. You should get from a square (x1; y1) to a square (x2; y2). Using the shortest path is not necessary. You can move on the field squares in four directions. That is, when you are positioned in any…

java图形设计_java图形界面设计含答案

十一章 图形用户界面程序设计入门一&#xff0e;选择题&#xff1a;1. 容器Panel和applet缺省使用的布局编辑策略是 BA、BorderLayout B、FlowLayoutC、GridLayout D、CarLayout2. .applet类的直接父类是&#xff1a; BA、Component类 B、Container类C、Frame类 D、Panel类3. .…

【qduoj - 夏季学期创新题】骑士游历(递推dp)

题干&#xff1a; 描述 输入 输入包含多组数据&#xff0c;第一行T表示数据组数接下来每行六个整数n&#xff0c;m&#xff0c;x1&#xff0c;y1&#xff0c;x2&#xff0c;y2(分别表示n&#xff0c;m&#xff0c;起点坐标&#xff0c;终点坐标) 输出 输出T行&#xff0c;表示…

java ee 6 源码_Java EE 6开发手册·高级篇(第4版)

资源名称&#xff1a;Java EE 6开发手册高级篇(第4版)内容简介&#xff1a;《Java EE 6 开发手册?高级篇(第4 版)》是一本面向实战、以示例为驱动、在Java 平台企业版6(Java EE 6)上开发企业级应用的指南。该指南基于The Java EE 6 Tutorial: Basic Concepts&#xff0c;Fourt…

【qduoj - 夏季学期创新题】矩形剖分(递归,dp)

题干&#xff1a; 描述 对一个给定的矩形&#xff0c;将其划分成尽可能少的正方形&#xff0c;输出正方形的最少个数。例如&#xff0c;如下图所示的情况&#xff0c;则输入为3和4&#xff0c;输出为4。 输入 输入两个整数中间用空格分开。 输出 输出最少分割成的正方形的个…

java8 nio_Java8之 NIO的学习

一、什么是NIO&#xff1f;Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API&#xff0c;可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的&#xff0c;但是使用的方式完全不同&#xff0c;NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式…