一直非常想写一个关于设计模式的系列。苦于没有时间,现在终于可以一个一个的写出来。很开心!
本文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);