您的位置:首页 > 健康 > 养生 > 【再探】设计模式—中介者模式、观察者模式及模板方法模式

【再探】设计模式—中介者模式、观察者模式及模板方法模式

2024/10/6 20:36:03 来源:https://blog.csdn.net/qq_25308331/article/details/139335658  浏览:    关键词:【再探】设计模式—中介者模式、观察者模式及模板方法模式

 中介者模式让多对多的复杂引用关系变成一对多,同时能通过中间类来封装多个类中的行为,观察者模式在目标状态更新时能自动通知给订阅者,模版方法模式则是控制方法的执行顺序,子类在不改变算法的结构基础上可以扩展功能实现。

1 中介者模式

需求:1)系统中对象之间存在复杂的引用关系,比如一对多,多对多等。系统结构耦合度很高,结构混乱且难以理解。2)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。在中间类中定义对象交互的公共行为。

1.1 中介者模式介绍

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

图 中介者模式 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<Component> 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{@Overridepublic 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);}@Overridevoid onClick() { // 输入操作throw new RuntimeException("暂不支持Text的点击事件");}@Overridevoid 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);}@Overridevoid onClick() {mediator.update(content,"text");}@Overridevoid 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);}@Overridevoid onClick() {mediator.update(null,"view");}@Overridevoid onRefresh(String content) {throw new RuntimeException("暂不支持Button的更新操作");}}}

1.2 优缺点

优点:

  1. 简化了对象之间的交互,将原本多对多的交互改成一对多。使得对象之间解耦。
  2. 可以通过中介者类来扩展对象的交互行为,当需要添加或改变交互行为时,只需要添加对应的中介者子类即可,符合开闭原则。
  3. 同事类可以更专注自身业务,而不必关心与其他同事类的交互。

缺点:

  1. 中介者类包含同事类之间大量的交互细节,使得该类变得非常复杂,不符合单一职责原则。
  2. 中介者类与同事类的耦合度高。

2 观察者模式

需求:当目标更新时,能自动通知给订阅者。

2.1 观察者模式介绍

当目标对象的状态发生改变时,它的所有观察者都会收到通知。

图 观察者模式 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 {@Overridepublic void beforeNotify(String content) {System.out.println("通知时间:" + new Date());}@Overridepublic void afterNotify(String content) {System.out.println("通知完成");}}private interface Observer {void update(String content);}private static class Student implements Observer {@Overridepublic void update(String content) {if (content.contains("放假")) System.out.println("学生,耶耶耶!");else System.out.println("学生,哦哦哦");}}private static class Teacher implements Observer {@Overridepublic void update(String content) {System.out.println("老师,收到:" + content);}}}

2.2 优缺点

优点:

  1. 当目标状态更新时,能自动发生通知给订阅者。
  2. 观察者与被观察者耦合度低,符合依赖倒置原则。

缺点:

  1. 当观察者数量较多时,通知耗时会加长。一个观察者的卡顿会影响整体执行效率

3 模版方法模式

需求:对方法的执行顺序有要求,而某些特定方法由子类去实现。例如想写排序算法,算法内部中方法的执行顺序相同,但具体排序算法由不同子类实现。

3.1 模版方法模式介绍

定义一个操作中的算法框架,将一些步骤延迟到子类中,子类在不改变算法的结构基础上重定义该算法的某些特定步骤。

图 模版方法模式 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 {@Overrideprotected void duty() {System.out.println("写bug AND 解决bug");}}}

3.2 优缺点

优点:

  1. 可以控制方法执行顺序,当要增加新的方法实现时,只需要添加特定子类。符合开闭原则及里氏替换原则。

缺点:

  1. 增加了类的个数。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com