本文主要是介绍【再探】设计模式—中介者模式、观察者模式及模板方法模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
中介者模式让多对多的复杂引用关系变成一对多,同时能通过中间类来封装多个类中的行为,观察者模式在目标状态更新时能自动通知给订阅者,模版方法模式则是控制方法的执行顺序,子类在不改变算法的结构基础上可以扩展功能实现。
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 优缺点
优点:
- 简化了对象之间的交互,将原本多对多的交互改成一对多。使得对象之间解耦。
- 可以通过中介者类来扩展对象的交互行为,当需要添加或改变交互行为时,只需要添加对应的中介者子类即可,符合开闭原则。
- 同事类可以更专注自身业务,而不必关心与其他同事类的交互。
缺点:
- 中介者类包含同事类之间大量的交互细节,使得该类变得非常复杂,不符合单一职责原则。
- 中介者类与同事类的耦合度高。
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 优缺点
优点:
- 当目标状态更新时,能自动发生通知给订阅者。
- 观察者与被观察者耦合度低,符合依赖倒置原则。
缺点:
- 当观察者数量较多时,通知耗时会加长。一个观察者的卡顿会影响整体执行效率
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 优缺点
优点:
- 可以控制方法执行顺序,当要增加新的方法实现时,只需要添加特定子类。符合开闭原则及里氏替换原则。
缺点:
- 增加了类的个数。
这篇关于【再探】设计模式—中介者模式、观察者模式及模板方法模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!