import java.util.*;
//负责帮忙监听的女同学
class GirlClassMate {
private String action; //前台秘书发现的情况
//给她送过礼的男同学们
private ArrayList<NbaWatcher> observers = new ArrayList<NbaWatcher>();
//增加,就是有几个同学请她帮们关照,就在集合中增加几个对象
public void Attach(NbaWatcher observer) {
observers.add(observer);
}
//从关照对象中删除对象
public void Delete(NbaWatcher observer) {
observers.remove(observer);
}
//通知关照看NBA的每一位同学,班主任来啦!
public void Notify() {
for (NbaWatcher observer : observers) {
observer.Update();
}
}
public void setAction(String action) {
this.action = action;
}
public String getAction() {
return action;
}
}
//看NBA的同学
class NbaWatcher {
private String name; //该同学的名字
private GirlClassMate wodi; //前排卧底MM
public void Update() {
// TODO Auto-generated method stub
System.out.println(wodi.getAction() + name + "别看球赛啦,继续学习!");
}
public NbaWatcher(String name, GirlClassMate wodi) {
this.name = name;
this.wodi = wodi;
}
}
public class MainClass {
public static void main(String[] args) {
GirlClassMate MM = new GirlClassMate(); //前台MM对象
NbaWatcher diaosi1 = new NbaWatcher("屌丝1", MM); //看股票的同事1
NbaWatcher diaosi2 = new NbaWatcher("屌丝2", MM); //看股票的同事1
//将两位屌丝同事加进前台MM的关照对象列表中
MM.Attach(diaosi1);
MM.Attach(diaosi2);
//前台MM发现老板回来了
MM.setAction("班主任回来啦!");
//通知关照列表中的每一位同事,老板回来了
MM.Notify();
}
}
输出结果:班主任回来啦!屌丝1别看球赛啦,继续学习! 班主任回来啦!屌丝2别看球赛啦,继续学习!你来评一评,这代码写的怎么样?肯定不好啦!前排女同学对象依赖于具体的看NBA同学对象,而NBA同学对象依赖于前排女同学对象。那么这样就形成了一种双向耦合的关系。在一段代码里面,耦合度过高可不是什么好事。用依赖倒转原则专业的话来说就是:具体应该依赖于抽象,抽象不应该依赖于具体。按照这个原则,我们将看NBA球赛的观察者,看漫画的观察者等等抽象出来一个观察者类。而无论是前排MM通知者,还是班主任这个通知者都是通知者,所以也可以抽象为一个通知者类。改进之后的代码如下:
import java.util.*;
//通知者,可能是班主任自己,也可能是前排女同学
abstract class Notifier {
private ArrayList<Observer> observers = new ArrayList<Observer>();
public void Attach(Observer observer) {
observers.add(observer);
}
public void Delete(Observer observer) {
observers.remove(observer);
}
//通知关照同学列表中每一位同事,班主任来了
public void Notify() {
for (Observer observer : observers) {
observer.Update();
}
}
abstract public void setAction(String action);
abstract public String getAction();
}
class Boss extends Notifier{
private String action; //通知者发现的情况
//老板发现的情况
public void setAction(String action) {
this.action = action;
}
public String getAction() {
return action;
}
}
class GirlClassMate extends Notifier{
private String action; //通知者发现的情况
//前台MM发现的情况
public void setAction(String action) {
this.action = action;
}
public String getAction() {
return action;
}
}
//Observer师祖
abstract class Observer {
protected String name; //该同学的名字
protected Notifier notifier; //事件通知者
abstract void Update();
public Observer(String name, Notifier notifier) {
this.name = name;
this.notifier = notifier;
}
}
//看NBA的的同事
class NbaWatcher extends Observer{
public NbaWatcher(String name, Notifier notifier) {
super(name, notifier);
// TODO Auto-generated constructor stub
}
public void Update() {
// TODO Auto-generated method stub
System.out.println(notifier.getAction() + name + "别看球赛啦,继续学习!");
}
}
//看世界杯的同事
class ComicReader extends Observer{
public ComicReader(String name, Notifier notifier) {
super(name, notifier);
// TODO Auto-generated constructor stub
}
public void Update() {
// TODO Auto-generated method stub
System.out.println(notifier.getAction() + name + "别看漫画啦,继续学习");
}
}
public class MainClass {
public static void main(String[] args) {
Notifier tuhao = new Boss(); //通知者换成班主任自己了
Observer diaosi1 = new NbaWatcher("倒霉的屌丝1", tuhao); //看NBA的同学
Observer diaosi2 = new ComicReader("幸运的屌丝2", tuhao); //看NBA的同学
//将两位屌丝同事加进前台MM的关照对象列表中
//tuhao.Attach(diaosi1); //倒霉的屌丝1,没有加进老板的关照列表,所以被抓住了
tuhao.Attach(diaosi2);
//前台MM发现老板回来了
tuhao.setAction("班主任我回来啦!");
//通知关照列表中的每一位同事,老板回来了
tuhao.Notify();
}
}
import java.util.*;
import java.lang.reflect.*;
//通知者,可能是老板,也可能是前台秘书
abstract class Notifier {
protected Method Update;
abstract public void setAction(String action);
abstract public void Notify(Object object);
}
class Boss extends Notifier{
private String action; //通知者发现的情况
//老板发现的情况
public void setAction(String action) {
this.action = action;
}
public void Notify(Object object) {
if (Update != null) {
try {
Update.invoke(object, action);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class GirlClassMate extends Notifier{
private String action; //通知者发现的情况
public Method Update; //反射事件
//老板发现的情况
public void setAction(String action) {
this.action = action;
}
public void Notify(Object object) {
if (Update != null) {
try {
Update.invoke(object, action);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//看股票的同事
class NbaWatcher {
protected String name; //该同事的名字
protected Notifier notifier; //前台卧底MM
public NbaWatcher(String name, Notifier notifier) {
this.name = name;
this.notifier = notifier;
}
public void CloseNbaWatcher(String action) {
// TODO Auto-generated method stub
System.out.println(action + name + "别看球赛啦,继续学习");
}
}
//看世界杯的同事
class ComicReader {
protected String name; //该同事的名字
protected Notifier notifier; //前台卧底MM
public ComicReader(String name, Notifier notifier) {
this.name = name;
this.notifier = notifier;
}
public void CloseComicReader(String action) {
// TODO Auto-generated method stub
System.out.println(action + name + "别看漫画啦,继续学习");
}
}
public class MainClass {
public static void main(String[] args) {
Notifier tuhao = new Boss();
NbaWatcher diaosi1 = new NbaWatcher("倒霉的屌丝1", tuhao);
ComicReader diaosi2 = new ComicReader("幸运的屌丝2", tuhao);
tuhao.setAction("班主任我回来啦!");
try {
tuhao.Update = diaosi1.getClass().getMethod("CloseNbaWatcher", new Class[] {String.class});
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tuhao.Notify((Object)diaosi1);
try {
tuhao.Update = diaosi2.getClass().getMethod("CloseComicReader", new Class[] {String.class});
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tuhao.Notify((Object)diaosi2);
}
}
发射实现委托核心:protected Method Update;
if (Update != null) {
try {
Update.invoke(object, action);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
tuhao.Update = diaosi2.getClass().getMethod("CloseComicReader", new Class[] {String.class});
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tuhao.Notify((Object)diaosi2);右上面代码可以看出,反射能够实现根据类的不同而调用不同的方法。就好像是C#中,一个委托可以搭载多个方法,所有方法一次被唤起。感觉上,也有点像c语言里面的钩子函数。班主任来啦之观察者模式,事件委托等Java实现---如果你还不懂,看完此文,就一定会懂
原文地址:http://blog.csdn.net/xiaxia__/article/details/41803473