(六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型) (十一)

2014-11-24 10:41:13 · 作者: · 浏览: 12
MoveEvent) {
System.out.println("--------鼠标移动代码---------");
System.out.println("alert('您当前鼠标的位置,x坐标为:"+mouseMoveEvent.getX()+",y坐标为:"+mouseMoveEvent.getY()+"')");
}
});
}

public Button getButton() {
return button;
}

}

//假设这个是我们写的某一个特定的jsp页面,里面可能有很多元素,input,form,table,等等
//我们假设只有一个按钮
public class ButtonJsp {

private Button button;

public ButtonJsp() {
super();
button = new Button();//这个可以当做我们在页面写了一个button元素
button.setId("submitButton");//取submitButton为id
button.setValue("提交");//提交按钮
button.setOnclick(new ClickListener() {//我们给按钮注册点击监听器
//按钮被点,我们就验证后提交
public void click(ClickEvent clickEvent) {
System.out.println("--------单击事件代码---------");
System.out.println("if('表单合法'){");
System.out.println("\t表单提交");
System.out.println("}else{");
System.out.println("\treturn false");
System.out.println("}");
}
});
button.setOnDblClick(new DblClickListener() {
//双击的话我们提示用户不能双击“提交”按钮
public void dblClick(DblClickEvent dblClickEvent) {
System.out.println("--------双击事件代码---------");
System.out.println("alert('您不能双击"+dblClickEvent.getButton().getValue()+"按钮')");
}
});
button.setOnMouseMove(new MouseMoveListener() {
//这个我们只简单提示用户鼠标当前位置,示例中加入这个事件
//目的只是为了说明事件驱动中,可以包含一些特有的信息,比如坐标
public void mouseMove(MouseMoveEvent mouseMoveEvent) {
System.out.println("--------鼠标移动代码---------");
System.out.println("alert('您当前鼠标的位置,x坐标为:"+mouseMoveEvent.getX()+",y坐标为:"+mouseMoveEvent.getY()+"')");
}
});
}

public Button getButton() {
return button;
}

}
以上可以认为我们给web服务中写了一个简单的页面,下面我们看客户在访问我们的页面时,我们的页面在做什么。

[java]

public class Client {

public static void main(String[] args) {
ButtonJsp jsp = new ButtonJsp();//客户访问了我们的这个JSP页面
//以下客户开始在按钮上操作
jsp.getButton().dblClick();//双击按钮
jsp.getButton().mouseMove(10, 100);//移动到10,100
jsp.getButton().mouseMove(15, 90);//又移动到15,90
jsp.getButton().click();//接着客户点了提交
}
}

public class Client {

public static void main(String[] args) {
ButtonJsp jsp = new ButtonJsp();//客户访问了我们的这个JSP页面
//以下客户开始在按钮上操作
jsp.getButton().dblClick();//双击按钮
jsp.getButton().mouseMove(10, 100);//移动到10,100
jsp.getButton().mouseMove(15, 90);//又移动到15,90
jsp.getButton().click();//接着客户点了提交
}
} 我们看运行结果可以看到,我们的三个事件都起了作用,最终提交了表单。

以上就是模拟整个JSP页面中,我们的按钮响应用户事件的过程,我相信通过这两个例子,各位应该对观察者模式和事件驱动都有了自己的理解和认识,二者都是用来处理变化与响应的问题,其中观察者更多的是发布-订阅,也就是类似读者和作者的关系,而事件驱动更多的是为了响应客户的请求,从而制定一系列的事件和监听器,去处理客户的请求与操作。

二者其实都是有自己的弱项的,只有掌握了模式的弱项才能更好的使用,不是有句话叫“真正了解一个东西,不是知道它能干什么,而是知道它不能干什么。”吗?

观察者模式所欠缺的是设计上的问题,即观察者和被观察者是多对一的关系,那么反过来的话,就无法支持了。

各位可以尝试将二者位置互换达到这个效果,这算是设计模式的活用,很简单,就是让被观察者做成一个接口,提供是否改变的方法,让观察者维护一个被观察者的列表,另外开启一个线程去不断的测试各个被观察者是否改变。由于本篇已经够长,所以LZ不再详细编写,如果有哪位读者有需要,可以在下方留言,LZ看到的话,如果有时间,会写出来放到资源里供各位下载

观察者模式还有一个缺点就是,每一个观察者都要实现观察者接口,才能添加到被观察者的列表当中,假设一个观察者已经存在,而且我们无法改变其代码,那么就无法让它成为一个观察者了,不过这个我们依然可以使用适配器模式解决。但是还有一个问题就不好解决了,就是假如我们很多类都是现成的,当被观察者发生变化时,每一个观察者都需要调用不同的方法,那么观察者模式就有点捉襟见肘的感觉了,我们必须适配每一个类去统一他们变