中介者模式让多对多的复杂引用关系变成一对多,同时能通过中间类来封装多个类中的行为,观察者模式在目标状态更新时能自动通知给订阅者,模版方法模式则是控制方法的执行顺序,子类在不改变算法的结构基础上可以扩展功能实现。
需求:1)系统中对象之间存在复杂的引用关系,比如一对多,多对多等。系统结构耦合度很高,结构混乱且难以理解。2)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。在中间类中定义对象交互的公共行为。
用一个中介对象来封装一系列的对象交互。使得各个对象不需要显式地相互引用,从而使其耦合度松散,而且可以独立地改变它们之间的交互。

图 中介者模式 UML
需求描述:在前端开发中,有三个组件 Button、View, 及Text. View 用来展示信息,Text 用于输入编辑信息,Button用来提交更新。用户在Text输入好内容后,点击Button后,内容会更新到View. 而点击View时,会把内容输入到Text。

图 需求分析图

图 需求分析UML
- public class NoMediatorPattern {
-
- public static void main(String[] args) {
- Text text = new Text();
- Button button = new Button();
- View view = new View();
-
- button.setText(text);
- button.setView(view);
- view.setText(text);
-
- button.click();
- view.click();
- button.click();
- }
-
- private static class Button {
-
- private Text text;
- private View view;
-
- public void setText(Text text) {
- this.text = text;
- }
-
- public void setView(View view) {
- this.view = view;
- }
-
- void click() {
- if (text != null && view != null) {
- view.onRefresh(text.generateText());
- }
- }
- }
-
- private static class Text {
-
- private String content;
-
- private String generateText() {
- if (content == null) content = "";
- Random random = new Random();
- content += random.nextInt();
- return content;
- }
-
- void onRefresh(String text) {
- content = text;
- }
- }
-
- private static class View{
-
- private Text text;
-
- private String content;
-
- public void setText(Text text) {
- this.text = text;
- }
-
- void click() {
- if (text != null) {
- text.onRefresh(content);
- }
- }
-
- void onRefresh(String text) {
- this.content = text; // 更新信息
- System.out.println("View中显示信息:" + text);
- }
- }
-
- }
上面代码中,需要考虑Button 与 Text、View,View 与Text 的交互。这使得系统逻辑变得更复杂。

图 中介者模式思维下的需求分析

图 中介者模式思维下的 UML
中介者模式下,只需要考虑中介者与各同事类的交互。
- public class MediatorPattern {
-
- public static void main(String[] args) {
-
- Mediator mediator = new ContentMediator();
-
- Component text = new Text(mediator, "text");
- Component button = new Button(mediator,"button");
- Component view = new View(mediator,"view");
-
- mediator.registry(text);
- mediator.registry(button);
- mediator.registry(view);
-
- button.onClick();
- button.onClick();
- view.onClick();
- button.onClick();
- }
-
- private static abstract class Mediator {
-
- protected final Set
components = new HashSet<>(); -
- public void registry(Component component) {
- if (component != null) {
- components.add(component);
- }
- }
-
- abstract void update(String content,String target);
-
- }
-
- private static class ContentMediator extends Mediator{
-
- @Override
- public void update(String content,String target) {
- if (content == null) {
- Text text = getText();
- if (text == null) throw new RuntimeException("没有更新内容");
- content = text.getContent();
- }
- for (Component component : components) {
- if (component.getTag().equals(target)) {
- component.onRefresh(content);
- }
- }
- }
-
- private Text getText() {
- for (Component component : components) {
- if ("text".equals(component.getTag())) return (Text) component;
- }
- return null;
- }
- }
-
- private static abstract class Component {
- protected final Mediator mediator;
- private final String tag;
-
- protected Component(Mediator mediator, String tag) {
- this.mediator = mediator;
- this.tag = tag;
- }
-
- public String getTag() {
- return tag;
- }
-
- abstract void onClick();
-
- abstract void onRefresh(String content);
- }
-
- private static class Text extends Component {
-
- private String content;
-
- protected Text(Mediator mediator, String tag) {
- super(mediator, tag);
- }
-
- @Override
- void onClick() { // 输入操作
- throw new RuntimeException("暂不支持Text的点击事件");
- }
-
- @Override
- void onRefresh(String content) {
- this.content = content;
- }
-
- public String getContent() {
- Random random = new Random();
- String temp = content;
- if (temp == null) temp = "";
- temp += random.nextInt() + "@";
- content = null;
- return temp;
- }
- }
-
- private static class View extends Component {
-
- private String content;
-
- protected View(Mediator mediator, String tag) {
- super(mediator, tag);
- }
-
- @Override
- void onClick() {
- mediator.update(content,"text");
- }
-
- @Override
- void onRefresh(String content) {
- this.content = content;
- System.out.println("view更新:"+ content);
- }
- }
-
- private static class Button extends Component {
-
- protected Button(Mediator mediator, String tag) {
- super(mediator, tag);
- }
-
- @Override
- void onClick() {
- mediator.update(null,"view");
- }
-
- @Override
- void onRefresh(String content) {
- throw new RuntimeException("暂不支持Button的更新操作");
- }
- }
-
- }
优点:
缺点:
需求:当目标更新时,能自动通知给订阅者。
当目标对象的状态发生改变时,它的所有观察者都会收到通知。

图 观察者模式 UML
- public class ObserverPattern {
-
- public static void main(String[] args) {
- Subject subject = new School();
-
- Observer observer1 = new Teacher();
- Observer observer2 = new Student();
- subject.attach(observer1);
- subject.attach(observer2);
-
- subject.notifyObserverList("快高考啦!");
- subject.notifyObserverList("六一放假");
- }
-
- private static abstract class Subject {
- protected final Set<Observer> observerList = new HashSet<>();
-
- public void attach(Observer observer) {
- observerList.add(observer);
- }
-
- public void detach(Observer observer) {
- observerList.remove(observer);
- }
-
- public void notifyObserverList(String content) {
- beforeNotify(content);
- for (Observer observer : observerList) observer.update(content);
- afterNotify(content);
- }
-
- public abstract void beforeNotify(String content);
-
- public abstract void afterNotify(String content);
-
- }
-
- private static class School extends Subject {
-
- @Override
- public void beforeNotify(String content) {
- System.out.println("通知时间:" + new Date());
- }
-
- @Override
- public void afterNotify(String content) {
- System.out.println("通知完成");
- }
- }
-
- private interface Observer {
- void update(String content);
- }
-
- private static class Student implements Observer {
- @Override
- public void update(String content) {
- if (content.contains("放假")) System.out.println("学生,耶耶耶!");
- else System.out.println("学生,哦哦哦");
- }
- }
-
- private static class Teacher implements Observer {
-
- @Override
- public void update(String content) {
- System.out.println("老师,收到:" + content);
- }
- }
-
- }
优点:
缺点:
需求:对方法的执行顺序有要求,而某些特定方法由子类去实现。例如想写排序算法,算法内部中方法的执行顺序相同,但具体排序算法由不同子类实现。
定义一个操作中的算法框架,将一些步骤延迟到子类中,子类在不改变算法的结构基础上重定义该算法的某些特定步骤。

图 模版方法模式 UML
- public class TemplateMethodPattern {
-
- public static void main(String[] args) {
- Worker programmer = new Programmer();
- programmer.work();
- }
-
- private static abstract class Worker {
-
- public void work() {
- punch("上班");
- duty();
- punch("下班");
- }
-
- protected abstract void duty();
-
- protected void punch(String content) {
- System.out.println("打卡:" + content);
- }
- }
-
- private static class Programmer extends Worker {
-
- @Override
- protected void duty() {
- System.out.println("写bug AND 解决bug");
- }
- }
-
- }
优点:
缺点: