设计模式之1 observer模式(第二版)

一直非常想写一个关于设计模式的系列。苦于没有时间,现在终于可以一个一个的写出来。很开心!吐舌头


本文word版本链接(可下载):

http://wenku.baidu.com/view/9648d11a52d380eb62946d2f.html



设计模式总章:

设计模式就是把简单的问题复杂化,带来的好处是系统的可扩展性。

用了设计模式以后:

                   复杂度增加

                   开发成本增加

                   维护成本降低

 

 

设计模式的基本原则是,添加,而不是修改。

1.      什么叫分析?(确定需求是什么)

分析就是要知道我要做什么。确定系统实现什么样的功能。

 

 

 

2.      什么叫设计?(实现需求)

设计就是我要怎么实现。

设计就是多种实现的手段当中选取一个。实现某个功能是使用什么样的方式。

 

用一个接口来封装一系列共同具有的特点。

各个监听类都去实现这个接口。

 

在被监听的类上加上addxxxlistener方法。

 

 

awt当中的事件:

事件源可以是,buttion,textField,textArea

事件是:ActionEvent

 

相对应的监听器是actionlistener。

 

通过配置文件来管理observer。

 

配置文件:

文件名:observer.properties

 

文件的内容:

observers=com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog

 

访问当前配置的文件的main方法:

 

package com.bjsxt.dp.observer;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

 

//事件类

class WakenUpEvent {

    privatelongtime;

    private Stringloc;

    private Childsource;

 

    //事件方法

    public WakenUpEvent(long time, String loc, Child source) {

       super();

       this.time = time;

       this.loc = loc;

       this.source = source;

    }

    publiclong getTime() {

        returntime;

    }

    publicvoid setTime(long time) {

       this.time = time;

    }

    publicStringgetLoc() {

       returnloc;

    }

    publicvoid setLoc(String loc) {

       this.loc = loc;

    }

    public Child getSource() {

       returnsource;

    }

    publicvoid setSource(Child source) {

       this.source = source;

    }

}

 

//被监听类。

class Childimplements Runnable {

    private List<WakenUpListener> wakenUpListeners =newArrayList<WakenUpListener>();

 

    publicvoid addWakenUpListener(WakenUpListener l) {

       wakenUpListeners.add(l);

    }

   

    void wakeUp() {

       for(int i=0; i<wakenUpListeners.size(); i++) {

           WakenUpListener l = wakenUpListeners.get(i);

           l.ActionToWakenUp(new WakenUpEvent(System.currentTimeMillis(),"bed",this));

       }

    }

 

    publicvoid run() {

       try {

           Thread.sleep(5000);

       } catch (InterruptedException e) {

           e.printStackTrace();

       }

      

       this.wakeUp();

    }

   

}

 

//监听类

class Dadimplements WakenUpListener {

 

    publicvoid ActionToWakenUp(WakenUpEvent wakenUpEvent) {

       System.out.println("feedchild");

    }

   

}

 

//监听类

class GrandFather implementsWakenUpListener {

 

    publicvoid ActionToWakenUp(WakenUpEvent wakenUpEvent) {

       System.out.println("hugchild");

    }

   

}

 

 

//监听类

class Dogimplements WakenUpListener {

 

    publicvoid ActionToWakenUp(WakenUpEvent arg0) {

       System.out.println("wang wang...");

    }

   

}

//监听接口

interface WakenUpListener {

    publicvoid ActionToWakenUp(WakenUpEvent wakenUpEvent);

}

 

//主类

publicclass Test {

    publicstaticvoid main(String[] args) {

       Child c = new Child();

      

       //通过split方法得到来自配置文件当中的多个observers.

       String[] observers = PropertyMgr.getProperty("observers").split(",");

 

       //对于每一个observer,把它添加上去。

       for(String s : observers) {

           try {

    //c是被监听类,也就是child

//s是监听类,也就是observers

//通过反射找到该类,并new出一个对象来,因为new出来的是object,所以转换成为wakenuplistener,并把这个wakenuplistener添加到chid上。       c.addWakenUpListener((WakenUpListener)(Class.forName(s).newInstance()));

           } catch (InstantiationException e) {

              e.printStackTrace();

           } catch (IllegalAccessException e) {

              e.printStackTrace();

           } catch (ClassNotFoundException e) {

              e.printStackTrace();

           }

       }

      

      

       new Thread(c).start();

    }

}

 

//配置文件管理类。

class PropertyMgr {

    //单例模式

privatestatic Propertiesprops =new Properties();

   

    static {

       try {

    //找到配置文件 props.load(Test.class.getClassLoader().getResourceAsStream("com/bjsxt/dp/observer/observer.properties"));

       } catch (IOException e) {

           e.printStackTrace();

       }

    }

   

    publicstatic String getProperty(String key) {

//拿到属性的值

       returnprops.getProperty(key);

    }

}

//预留为其他的类做准备。

class CryEvent {

}

 

abstractclass Event {

 

}

1.      在observers模式当中,类的结构比较复杂。还是来一个一个的重新理一遍。

需要:被监听类,监听类(可以是多个),事件类,XXXListener接口,主类(也就是使用者)

 

2.      从被监听类说起,被监听的类(child类,对照awt当中的buttion),来实现多线程,本例中为实现runnable接口。在被监听的类当中应该有一个ArrayList。这个list里面放的是,监听器。所以被监听的类当中要实现addWakenUpListener(对照awt当中的addActionListener)方法。当然这个类当中还需要有wakeUp(对照awt当中的buttonPressed)方法,用来激活每一个监听器。作为实现了runnable接口的类,必须有run方法。

addWakenUpListener方法在使用者当中被调用。需要用到哪个observer,就把哪个observer添加上去。

 

wakeup(对照awt当中的buttonPressed)方法从arrayList当中读取每一个listener。调用每一个listener的ActionToWakenUp对照awt当中的actionPerformed)方法。ActionToWakenUp方法的参数,是事件类WakenUpEvent(对照awt当中的ActionEvent)的对象。所以这里调用的是事件类WakenUpEvent(对照awt当中的ActionEvent)的构造方法去new出一个对象:newWakenUpEvent(System.currentTimeMillis(),"bed",this)

(对应awt当中的new ActionEvent(System.currentTimeMillis(),this)

 

3.      事件类是WakenUpEvent(对照awt当中的ActionEvent),当中的构造方法是public WakenUpEvent(long time,String loc, Child source)。(对应awt当中的new ActionEvent(System.currentTimeMillis(),this)

 

4.      WakenUpListener(对照awt当中的ActionListener)接口:非常的简单,提供了一个统一的方法:public void ActionToWakenUp(WakenUpEvent wakenUpEvent) 对照awt当中的publicvoid actionPerformed(ActionEvent e);;

 

5.      监听类非常的简单,都实现了WakenUpListener(对照awt当中的ActionListener)接口。而且都只有一个方法,public void ActionToWakenUp(WakenUpEvent wakenUpEvent) 对照awt当中的publicvoid actionPerformed(ActionEvent e);)。

 

 

模拟的awt当中的事件响应:

 

package com.bjsxt.dp.observer.awt;

 

import java.util.ArrayList;

import java.util.List;

 

//主类

publicclass Test {

    publicstaticvoid main(String[] args) {

       Button b = new Button();

       b.addActionListener(new MyActionListener());

       b.addActionListener(new MyActionListener2());

       b.buttonPressed();

    }

}

 

//button类,也就是被监听类。

class Button {

    //监听类的list

    private List<ActionListener> actionListeners =newArrayList<ActionListener>();

   

//触发事件的方法

    publicvoid buttonPressed() {

       ActionEvent e = new ActionEvent(System.currentTimeMillis(),this);

 

//每个监听类都去响应actionperformed方法。只是每个监听器可以有不同的具体实现。

       for(int i=0; i<actionListeners.size(); i++) {

           ActionListener l = actionListeners.get(i);

           //调用actionperformed方法。

           l.actionPerformed(e);

       }

    }

 

    //添加监听器的方法

    publicvoid addActionListener(ActionListener l) {

       actionListeners.add(l);

    }

}

 

//监听器接口

interface ActionListener {

    publicvoid actionPerformed(ActionEvent e);

}

 

//监听类

class MyActionListenerimplements ActionListener {

 

    publicvoid actionPerformed(ActionEvent e) {

       System.out.println("buttonpressed!");

    }

   

}

 

//监听类

class MyActionListener2implements ActionListener {

 

    publicvoid actionPerformed(ActionEvent e) {

       System.out.println("buttonpressed 2!");

    }

   

}

 

 

//事件类

class ActionEvent {

   

    longwhen;

    Object source;

    //事件方法

    public ActionEvent(long when, Object source) {

       super();

       this.when = when;

       this.source = source;

    }

   

   

    publiclong getWhen() {

       returnwhen;

    }

 

    public Object getSource() {

       returnsource;

    }

   

}

 

核心思想:

 

1.      再来看模拟的awt当中的事件响应

 

2.      再从被监听类说起,button类。同样在被监听类当中有一个ArrayList. 同样在这个list里面放的是监听器。所以被监听的类当中要是实现addxxxlistener方法。当然这个类当中还需要buttionPressed方法,用来激活每一个监听器。buttionPressed就是触发事件的方法。唯一的区别,就是在awt当中没有实现多线程,所以不需要

在buttonPressed方法当中,同样从ArrayList当中读取每一个listener。同样调用每一个listener的actionPerformed方法。同样actionPerformed方法的参数,是事件类(ActionEvent)的对象。只不过这里,先new出来一个ActionEvent的对象,并把这个ActionEvent的对象e,作为actionPerformed方法的参数。

addActionListener方法在使用者当中被调用。需要用到哪个observer,就把哪个observer添加上去。

 

 

3.      事件类是ActionEvent,当中的构造方法是public ActionEvent(long when, Objectsource)

 

4.      ActionListener接口:非常的简单,提供了一个统一的方法: public void actionPerformed(ActionEvent e);

 

5.      监听类们非常的简单,都实现了ActionListener接口。而且都只有一个方法 public void actionPerformed(ActionEvent e);

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值