什么是观察者模式?
指多个对象存在一对多的依赖关系,当一个对象(观察者)那个发生改变时,所有依赖于他的对象(目标)都得到通知并被自动更新。这种模式又称为 发布-订阅模式、模型-视图模式,他是对象行为型模式
优点?
- 降低了目标与观察者之间的耦合关系。符合依赖倒置原则
- 当观察者对象过多时,通知的发布会花费很多时间
先看一个小demo:
报社 :有生产 报 的方法
读者 :有读报 的方法 有三类读者
报 : domain
分析累与类的关系:
报社 与 报:生产报
报社 与 读者: 读者 读 去报社生产的报(依赖关系)
代码如下:
Paper
package javas.observer; public class Paper { private String name; public Paper(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Public
package javas.observer; public class Public { private String name; public Public(String name) { this.name = name; } public Paper generatePaper(){ return new Paper("人民日报"); } public String getName() { return name; } }
Reader
package javas.observer; public interface Reader { void read(Public p); }
ReadOne
package javas.observer; public class ReadOne implements Reader{ private String name; public ReadOne(String name) { this.name = name; } public void read(Public p){ System.out.println(this.name+" 读了 "+p.getName()+" 的 "+p.generatePaper().getName()+" 报纸"); } }
ReadTwo
package javas.observer; public class ReadTwo implements Reader{ private String name; public ReadTwo(String name) { this.name = name; } public void read(Public p){ System.out.println(this.name+" 读了 "+p.getName()+" 的 "+p.generatePaper().getName()+" 报纸"); } }
ReadThree
package javas.observer; public class ReadThree implements Reader{ private String name; public ReadThree(String name) { this.name = name; } public void read(Public p){ System.out.println(this.name+" 读了 "+p.getName()+" 的 "+p.generatePaper().getName()+" 报纸"); } }
Test
package javas.observer; public class Test { public static void main(String[] args) { Public p = new Public("新华日报"); Reader ro = new ReadOne("张三"); Reader rt = new ReadTwo("李四"); Reader rh = new ReadThree("王五"); ro.read(p); rt.read(p); rh.read(p); } }
两个问题:
创建读者对象方式太麻烦:解决方法 使用反射 ioc(对象控制权反转) di(依赖注入)
每个读者对象都需要主动做事:
观察者设计模式: 一个对象和一堆对象的关系 (一个对象做事情 一堆对象自动做事情)
观察者: 报社
目标对象:读者
只要报社出版了报纸就让读者读报纸
改进
反射
package javas.observer; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Scanner; public class MySpring { public static Object getInstance(String className) { Object obj = null; Scanner scanner = new Scanner(System.in); try { Class aClass = Class.forName(className); // 控制权反转 Constructor con = aClass.getDeclaredConstructor(); obj = con.newInstance(); // 依赖注入:获取set方法 Field[] fields = aClass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { // 获取其类型 Class fieldType = fields[i].getType(); // 获取其属性名 String fileName = fields[i].getName(); // 拼接 setName 方法 StringBuilder setMethod = new StringBuilder("set"); String first = fileName.substring(0, 1).toUpperCase(); String other = fileName.substring(1); setMethod.append(first); setMethod.append(other); // 获取set方法 Method method = aClass.getDeclaredMethod(String.valueOf(setMethod), fieldType); // // 八个基本类型的包装类中 只有char类型没有带String参数的方法 Constructor typeCon = fieldType.getDeclaredConstructor(String.class); System.out.println("请输入"+fileName); String s = scanner.nextLine(); method.invoke(obj,typeCon.newInstance(s)); } } catch (Exception e) { e.printStackTrace(); } return obj; } }
Public
package javas.observer; import java.util.ArrayList; public class Public { private String name; public Public(String name) { this.name = name; } public Paper generatePaper(){ return new Paper("人民日报"); } public String getName() { return name; } // 反转类与类的设计模式:变为 has a的关系 private ArrayList<Reader> readers = new ArrayList<>(); public void addReader(Reader reader){ readers.add(reader); } public void removeReader(Reader reader){ readers.remove(reader); } public void sendInfoToReader(){ for (int i = 0; i < readers.size(); i++) { this.readers.get(i).read(this); } } }
Test
package javas.observer; public class Test { public static void main(String[] args) { Public p = new Public("新华日报"); // 反射技术 ReadOne ro = (ReadOne)MySpring.getInstance("javas.observer.ReadOne"); ReadTwo rt = (ReadTwo) MySpring.getInstance("javas.observer.ReadTwo"); ReadThree rh = (ReadThree) MySpring.getInstance("javas.observer.ReadThree"); p.addReader(ro); p.addReader(rt); p.addReader(rh); p.sendInfoToReader(); } }
其他不变
观察者模式
最新推荐文章于 2024-05-06 01:28:38 发布