观察者模式体验就是一个:
问题:在做UI设计时,遇到一个问题,就是当我点击一个自定义对话框的复选框时,自定义对话框的父界面必须做出相应的改变,还有,自定义对话框是做成的组件,应用于很多场合(有很多的界面用到此对话框);
//这是自定义的对话框,当事件是checkbox时,让父界面做//出改变
Public class DialogBox implements ClickListener {
Public void onClick(event e){
}
}
//这是父界面,他弹出对话框
Public class ParentFrame extends ParentClass{
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
}
解决方案一:
我把父界面的父类改变成自定义的父类,让父界面继承自定义的父类:
Public class DialogBox implements ClickListener{
Private Ojbect object = null ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
//当事件是checkbox时,强制转换成Custom调用//update方法
((Custom)object).update();
}
}
}
//这是自定义类,它继承了ParentClass,并抽象了个update方//法
Public abstact CustomClass extends ParentClass{
Public abstract void update() ;
}
Public class ParentFrame extends CustomClass {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
Public void update(){
//父界面的更新操作
}
}
这个解决方案确实解决的问题,当自定义对话框点击checkbox时,确实会使他的父界面发生改变,但他的缺点太大:必须继承CustomClass才能具备这样的功能,而且主要是因为他改变了继承关系,在ParentFrame和ParentClass之间加了一层,这样使耦合度加大了;而且每次都把自身的引用通过构造传过去(new DialogBox(this)),在dialogbox那边还要强行转换回来,确实不是什么好办法J
解决方案二:
//定义CustomListener接口
Public interface CustomListener (){
Public void update() ;
}
Public class DialogBox implements ClickListener{
Private Ojbect object = null ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
//当事件是checkbox时,强制转换成Custom调用//update方法
((CustomListener)object).update();
}
}
}
//实现了CustomListener接口
Public class ParentFrame extends ParentClass implements CustomListener {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
Public void update(){
//父界面的更新操作
}
}
这个解决方案也是解决了问题,尤其对第一解决方案而言,这个已经不会打乱继承关系,但是还没有脱离第二个缺陷;
解决方案三:
//定义Listener接口
Public interface CustomListener(){
Public void update() ;
}
//定义event接口
Public interface CustomEvent(){
Public void addCustomListener(CustomListener listener) ;
Public void removeCustomListener(CustomListener listner) ;
Public void notify() ;
}
Public class DialogBox implements ClickListener, CustomEvent {
Private List listenerList = new ArrayList() ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
notify() ;
}
}
//注册一个观察者
Public void addCustomListener(CustomListener listener) {
listenerList.add(listener) ;
}
//删除一个观察者
Public void removeCustomListener(CustomListener listner){
listenerList.remove(listener) ;
}
//调用所以注册的观察者
Public void notify() {
If(listenerList != null && !( listenerList.isEmpty)){
for(int I = 0 ; I < listenerList.size() ; I ++){
((CustomListener)listenerList.get(i)).update();
}
}
}
}
//实现了CustomListener接口
Public class ParentFrame extends ParentClass implements CustomListener {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox() ;
dialogbox. addCustomListener((CustomListener)this) ;
}
Public void update(){
//父界面的更新操作
}
}
第三中解决方案才是观察者模式是应用,这才是较为合理的方案;
观察者模式应用前提是:有一个对象出发事件时,其他对象也发生改变;是个一对多的关系