java设计优化--观察者模式

  • 观察者模式介绍

  观察者模式是一种非常有用的设计模式,在软件系统中,当一个对象的行为依赖于另一个对象的状态时,观察者模式就非常有用。如果不适用观察者模式,而实现类似的功能,可能就需要另外启动一个线程不停地监听另一个对象的状态,这样会得不偿失。如果在一个复杂的系统中,可能就需要开启很多的线程来监听对象状态的变化,这样会使系统的性能产生额外的负担。而观察者模式就可以在单线程下使某一对象及时得知所依赖对象状态的变化而做出行为。

  观察者模式的经典结构:

  

  其中ISubject是观察对象(被观察者对象),它维持着一个观察者对象列表,可以增加或删除观察者。IObserver是观察者,它依赖于ISubject对象状态的变化而做出行为。当ISubject对象的状态发生变化时,它可以通过inform()方法通知观察者。

  观察者模式的主要角色功能如下图:

  

  • 观察者实例

  现在简单实现一个观察者的小例子。

  主题接口:

1 public interface ISubject {
2     void attach(IObserver observer);
3     void detach(IObserver observer);
4     void inform();
5 }

  观察者接口:

1 public interface IObserver {
2     void update(Event event);
3 }

  事件(对应现实中的点击等事件也可以理解为上文中说到的状态变化):

1 public class Event {
2
3 }

  具体的主题实现:

 1 public class ConcreteSubject implements ISubject {
 2     Vector<IObserver> obversers = new Vector<IObserver>();//观察者队列
 3     @Override
 4     public void attach(IObserver observer) {
 5         obversers.add(observer);
 6     }
 7
 8     @Override
 9     public void detach(IObserver observer) {
10         obversers.remove(observer);
11     }
12
13     @Override
14     public void inform() {
15         Event event = new Event();
16         for(IObserver obverser:obversers){
17             obverser.update(event);
18         }
19     }
20
21 }

  具体的观察者:

1 public class ConcreteObserver implements IObserver {
2
3     @Override
4     public void update(Event event) {
5         System.out.println("ConcreteObserver.update()");
6     }
7
8 }

  测试代码:

public class Test {
    public static void main(String[] args) {
        IObserver observer1 = new ConcreteObserver();
        IObserver observer2 = new ConcreteObserver();
        ISubject subject = new ConcreteSubject();
        subject.attach(observer1);
        subject.attach(observer2);
        subject.inform();
    }
}

  可以看出,通过被观察者状态变化而调用某一方法使观察者收到通知而做出反应,通过委托降低了代码的耦合度。

  观察者模式十分常用,以致于JDK内部就为开发人员准备了一套观察者模式的实现。在java.util包中,就包括了Obserable类和Observer接口。在Observable中就实现了观察对象的主要功能,如:添加观察者、删除观察者和通知观察者等。Observer是观察者接口,它的update方法会在Obserable类的notifyObservers()中被回调以获得最新的状态变化。

  以现在比较火热的购房作为观察者模式的一个例子:现在很多购房者关注房价的变化,每当房价发生变动的时候,购房者就会收到通知。这样购房者就是观察者,他们关注着房子的价格。

  观察对象房子代码:

 1 public class House extends Observable{
 2     private float price;
 3
 4     public House(float price) {
 5         super();
 6         this.price = price;
 7     }
 8
 9     public float getPrice() {
10         return price;
11     }
12
13     public void setPrice(float price) {
14         super.setChanged();//设置变化点
15         super.notifyObservers(price);//价格变动
16         this.price = price;
17     }
18
19     @Override
20     public String toString() {
21         // TODO Auto-generated method stub
22         return "房子的价格为:"+this.price;
23     }
24 }

  观察者购房者代码:

 1 public class CustomerObserver implements Observer{
 2
 3     private String name;
 4
 5     public CustomerObserver(String name) {
 6         super();
 7         this.name = name;
 8     }
 9
10     @Override
11     public void update(Observable o, Object arg) {
12         if (arg instanceof Float) {
13             System.out.println(this.name+"观察到房子价格变动为:"+arg);
14         }
15     }
16 }

  测试代码:

 1 public class Test1 {
 2     public static void main(String[] args) {
 3         House h = new House(1000000) ;
 4         CustomerObserver hpo1 = new CustomerObserver("购房者A") ;
 5         CustomerObserver hpo2 = new CustomerObserver("购房者B") ;
 6         CustomerObserver hpo3 = new CustomerObserver("购房者C") ;
 7         h.addObserver(hpo1) ;
 8         h.addObserver(hpo2) ;
 9         h.addObserver(hpo3) ;
10         System.out.println(h) ; // 输出房子价格
11         h.setPrice(666666) ;    // 修改房子价格
12         System.out.println(h) ; // 输出房子价格
13     }
14 }

  输出结果为:

1 房子价格为:1000000.0
2 购房者C观察到价格更改为:666666.0
3 购房者B观察到价格更改为:666666.0
4 购房者A观察到价格更改为:666666.0
5 房子价格为:666666.0

  Observer源码:

 1 public class Observable {
 2     private boolean changed = false;//判断观察对象是否发生变化
 3     private Vector obs;//观察者队列
 4     public Observable() {
 5         obs = new Vector();
 6     }
 7
 8
 9     public synchronized void addObserver(Observer o) {
10         if (o == null)
11             throw new NullPointerException();
12         if (!obs.contains(o)) {
13             obs.addElement(o);
14         }
15     }
16
17     public synchronized void deleteObserver(Observer o) {
18         obs.removeElement(o);
19     }
20
21
22     public void notifyObservers() {
23         notifyObservers(null);
24     }
25
26   //通知观察者
27     public void notifyObservers(Object arg) {
28
29         Object[] arrLocal;
30
31         synchronized (this) {
32
33             if (!changed)
34                 return;
35             arrLocal = obs.toArray();
36             clearChanged();
37         }
38
39         for (int i = arrLocal.length-1; i>=0; i--)
40             ((Observer)arrLocal[i]).update(this, arg);
41     }
42
43
44     public synchronized void deleteObservers() {
45         obs.removeAllElements();
46     }
47
48
49     protected synchronized void setChanged() {
50         changed = true;
51     }
52
53
54     protected synchronized void clearChanged() {
55         changed = false;
56     }
57
58
59     public synchronized boolean hasChanged() {
60         return changed;
61     }
62
63
64     public synchronized int countObservers() {
65         return obs.size();
66     }
67 }

  可以发现JDK中实现的观察者模式,用法简单功能强大,和我们上面写的观察者模式实现原理是一样的。观察者模式可以用于事件监听、通知发布等场合,可以确保观察者在不适用轮询监控的情况下,可以及时得到相关消息和事件。

时间: 2024-10-25 02:15:34

java设计优化--观察者模式的相关文章

java设计优化--代理模式

代理模式使用代理对象完成用户的请求,屏蔽用户对真实对象的访问. 代理模式的用途很多,比如因为安全原因,需要屏蔽客户端直接访问真实对象:或者在远程调用中,需要使用代理对象处理远程方法中的技术细节:或者为了提升系统,对真是对象进行封装,从而达到延迟加载的目的. 在系统启动时,将消耗资源最多的方法使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间.在用户真正在做查询是,再由代理类加载真实的类,完成用户请求.这就是使用代理模式达到延迟加载的目的. 1.静态代理实现: 主题接口: 1 publ

java设计优化--单例模式

单例模式是一种对象创建模式,确保系统中一个类只有一个实例. 在java语言中,这样做有两大好处: 1.对于频繁使用的对象,可以省略创建对象所话费的时间: 2.由于new操作的次数减少,对于系统内存的使用频率降低,这样减少GC的压力,缩短GC停顿的时间. 单例模式细分: 1. 1 public class Singleton{ 2 private Singleton(){ 3 System.out.println("Singleton.Singleton()"); 4 } 5 6 pri

java设计优化-享元模式

享元模式是设计模式中少数几个以调高系统性能为目的的设计模式.它的核心思想是:如果在一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必为每一次使用都创建新的对象.在享元模式中,由于需要构建和维护这些可以共享的对象,因此,常常会出现一个工厂类,用于维护和创建对象. 享元模式对性能提升的主要帮助有两点: 1.可以节省重复创建对象的开销,因为被享元模式维护的相同对象只会被创建一次,当对象创建比较耗时时,便可以节省大量时间: 2.由于创建对象的数量减少,所有对系统内存的需求也减少,这样使GC

Java程序性能优化——设计优化

原文出自:http://blog.csdn.net/anxpp/article/details/51914119,转载请注明出处,谢谢! 1.前言 OK,之前写了一篇文章:"23种设计模式介绍以及在Java中的应用"详细介绍了如何将设计模式应用到Java编程中,而本文旨在介绍如何利用他们优化我们的程序,使其性能更佳. 设计模式的详细介绍请参照上面链接中的文章,不是本文的重点. 而Java程序的性能优化,不一定就仅仅是以提高系统性能为目的的,还可能是以用户体验.系统可维护性等为目的. 2

Java 性能优化系列之1[设计与程序优化]

性能 一般来说,性能通过以下几个方面来表现: 执行速度 内存分配 启动时间 负载承受能力 定量评测的性能指标: 执行时间 CPU时间 内存分配 磁盘吞吐量 网络吞吐量 响应时间 调优的层面 设计调优 代码调优 JVM调优 数据库调优 操作系统调优 性能调优必须有明确的目标,不要为了调优而调优,如果当前程序并没有明显的性能问题,盲目地进行调整,其风险可能远远大于收益. 设计优化 1. 单例模式 对于系统的关键组件和被频繁使用的对象,使用单例模式可以有效地改善系统的性能 2. 代理模式 代理模式可以

《Java程序性能优化》学习笔记 Ⅰ设计优化

豆瓣读书:http://book.douban.com/subject/19969386/ 第一章 Java性能调优概述 1.性能的参考指标 执行时间: CPU时间: 内存分配: 磁盘吞吐量: 网络吞吐量: 响应时间: 2.木桶定律   系统的最终性能取决于系统中性能表现最差的组件,例如window系统内置的评分就是选取最低分.可能成为系统瓶颈的计算资源如,磁盘I/O,异常,数据库,锁竞争,内存等. 性能优化的几个方面,如设计优化,Java程序优化,并行程序开发及优化,JVM调优,Java性能调

JAVA性能优化的五种方式

一,JAVA性能优化之设计优化 设计优化处于性能优化手段的上层.它往往须要在软件开发之前进行.在软件开发之前,系统架构师应该就评估系统可能存在的各种潜在问题和技术难点,并给出合理的设计方案,因为软件设计和系统架构对软件总体设计质量有决定性的影响.所以,设计调优对系统的性能影响也是最大的,假设说,代码优化.JVM优化都是对系统微观层次的"量"的优化,那设计优化就是对系统"质"的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是改良组件的实现;比方:

Java 程序优化 (读书笔记)

--From : JAVA程序性能优化 (葛一鸣,清华大学出版社,2012/10第一版) 1. java性能调优概述 1.1 性能概述 程序性能: 执行速度,内存分配,启动时间, 负载承受能力. 性能指标: 执行时间,CPU时间,内存分配,磁盘吞吐量,网络吞吐量,响应时间. 优化策略: 木桶原理,优化性能瓶颈. 1.2 性能调优的层次 设计调优, 代码调优, JVM调优, 数据库调优, 操作系统调优. 2. 设计优化 2.1 善用设计模式 单例模式: 对于巨大对象,节省创建对象的时间空间: 代理

JAVA性能优化分布式架构和部署

一,JAVA性能优化之设计优化 设计优化处于性能优化手段的上层.它往往须要在软件开发之前进行.在软件开发之前,系统架构师应该就评估系统可能存在的各种潜在问题和技术难点,并给出合理的设计方案,因为软件设计和系统架构对软件总体设计质量有决定性的影响.所以,设计调优对系统的性能影响也是最大的,假设说,代码优化.JVM优化都是对系统微观层次的“量”的优化,那设计优化就是对系统”质”的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是改良组件的实现;比方:组件A通过循环监控不断的检測时