请选择 进入手机版 | 继续访问电脑版
本站特色:极好的技术研究氛围!所有技术交流,必有回复!

疯狂Java联盟

 找回密码
 加入联盟
查看: 9632|回复: 16

事件监听机制1

[复制链接]
发表于 2008-7-23 20:25:18 | 显示全部楼层 |阅读模式
事件监听机制1

当初学习java的事件监听器的时候,一直都不太明白,想了很久也没想通到底是什么一个机制,相信很多人也有同感,一直到最近,突然脑袋开窍了,有点豁然开朗的感觉。。所以把我的感悟分享给大家。。


李老师当初给我们讲课的时候。。举例是消防员灭火的- -。。。虽然恶搞了点。。但是我就以这个为例吧。。



首先,我们分析下,起火的过程吧。。首先,要有个House对象,当中有个方法,发生了起火这个事件。那么,我们首先建立一个类House其中有个方法是起火。


超级简单的代码。。

Version 0.1

  1. public class ListenterTest
  2. {

  3. public static void main(String[] args)

  4. {

  5. new House().fired();

  6. }
  7. }

  8. class House
  9. {

  10. public void fired()

  11. {

  12. System.out.println("==起火了==");

  13. }
  14. }
复制代码


运行的结果:系统控制台输出=============起火了==============




好了,基本上,我们已经实现一个房子起火的过程了,接下来。。就会觉得。。房子还要我去调用起火的方法。。。(我是纵火犯)。。好像有点傻。。恩。那么我们就让房子是一个线程。。5秒后就会自动起火。。这里用了个线程。。大家不明处去研究多线程。。

Version 0.2

  1. public class Listenter
  2. {

  3. public static void main(String[] args)

  4. {

  5. new House().start();

  6. }
  7. }

  8. class House extends Thread
  9. {

  10. public void run()

  11. {

  12. try

  13. {

  14. sleep(5000);

  15. fired();

  16. }

  17. catch (Exception e)

  18. {

  19. System.out.println("==房子起火因为不明原因熄灭了==");

  20. }

  21. }

  22. public void fired()

  23. {

  24. System.out.println("=======起火了======");

  25. }
  26. }
复制代码


恩。。。现在房子已经可以自动起火了。。那么。。下面要有个消防员出现了。。当房子起火的时候,需要消防员救火。不过我英文不太好,所以消防员就叫FireSavior -0-。。。恩。。大家明白意思就行了。。

Version 0.3

  1. public class Listenter
  2. {

  3. public static void main(String[] args)

  4. {

  5. House house = new House();

  6. house.start();

  7. new FireSavior(house).start();

  8. }
  9. }

  10. class House extends Thread
  11. {

  12. boolean isFire = false;

  13. public boolean alert()

  14. {

  15. return isFire;

  16. }

  17. public House()

  18. {

  19. }

  20. public void run()

  21. {

  22. try

  23. {

  24. sleep(5000);

  25. fired();

  26. }

  27. catch (Exception e)

  28. {

  29. System.out.println("==房子起火因为不明原因熄灭了==");

  30. }

  31. }

  32. public void fired()

  33. {

  34. System.out.println("=======起火了======");

  35. isFire = true;

  36. }
  37. }

  38. class FireSavior extends Thread
  39. {

  40. House house;

  41. public FireSavior(House house)

  42. {

  43. this.house = house;

  44. }

  45. public void getFired()

  46. {

  47. System.out.println("==消防员把火扑灭了==");

  48. }


  49. public void run()

  50. {

  51. try

  52. {

  53. while (house.alert())

  54. {

  55. sleep(1000);

  56. getFired();

  57. }

  58. }

  59. catch (Exception e)

  60. {

  61. System.out.println("==消防员灭火失败==");

  62. }

  63. }
  64. }
复制代码


这个类运行是有问题的。大家会发现,虽然消防员线程运行启动了,但是并没有如我们期望的那样,在起火的时候把火扑灭。原因在哪的,while (house.alert())就在这里,当这样判断的时候,消防员只会在线程启动的时候判断一次房子是否起火了。。发现没起火,于是就不管了。。为了让他一直检查房子,所以我们把那个线程设为死线程,代码如下:

Version 0.4

  1. public class Listenter
  2. {

  3. public static void main(String[] args)

  4. {

  5. House house = new House();

  6. house.start();

  7. new FireSavior(house).start();

  8. }
  9. }

  10. class House extends Thread
  11. {

  12. boolean isFire = false;

  13. public boolean alert()

  14. {

  15. return isFire;

  16. }

  17. public House()

  18. {

  19. }

  20. public void run()

  21. {

  22. try

  23. {

  24. sleep(5000);

  25. fired();

  26. }

  27. catch (Exception e)

  28. {

  29. System.out.println("==房子起火因为不明原因熄灭了==");

  30. }

  31. }

  32. public void fired()

  33. {

  34. System.out.println("=======起火了======");

  35. isFire = true;

  36. }
  37. }

  38. class FireSavior extends Thread
  39. {

  40. House house;

  41. public FireSavior(House house)

  42. {

  43. this.house = house;

  44. }

  45. public void getFired()

  46. {

  47. System.out.println("==消防员把火扑灭了==");

  48. }


  49. public void run()

  50. {

  51. try

  52. {

  53. while (true)

  54. {

  55. if (house.alert())

  56. {

  57. sleep(1000);

  58. getFired();

  59. break;

  60. }

  61. }

  62. }

  63. catch (Exception e)

  64. {

  65. System.out.println("==消防员灭火失败==");

  66. }

  67. }
  68. }
复制代码

现实生活中,起火了不仅要有消防员救火,还有警察救人,因此,我们再加一个警察类。里面也只有一个简单的方法和消防员一样只输出一行简单的字。警察救人成功。
Version 0.5

  1. public class Listenter
  2. {

  3. public static void main(String[] args)

  4. {

  5. House house = new House();

  6. house.start();

  7. new FireSavior(house).start();
  8. new Police(house).start();

  9. }
  10. }

  11. class House extends Thread
  12. {

  13. boolean isFire = false;

  14. public boolean alert()

  15. {

  16. return isFire;

  17. }

  18. public House()

  19. {

  20. }

  21. public void run()

  22. {

  23. try

  24. {

  25. sleep(5000);

  26. fired();

  27. }

  28. catch (Exception e)

  29. {

  30. System.out.println("==房子起火因为不明原因熄灭了==");

  31. }

  32. }

  33. public void fired()

  34. {

  35. System.out.println("=======起火了======");

  36. isFire = true;

  37. }
  38. }

  39. class FireSavior extends Thread
  40. {

  41. House house;

  42. public FireSavior(House house)

  43. {

  44. this.house = house;

  45. }

  46. public void getFired()

  47. {

  48. System.out.println("==消防员把火扑灭了==");

  49. }


  50. public void run()

  51. {

  52. try

  53. {

  54. while (true)

  55. {

  56. if (house.alert())

  57. {

  58. sleep(1000);

  59. getFired();

  60. break;

  61. }

  62. }

  63. }

  64. catch (Exception e)

  65. {

  66. System.out.println("==消防员灭火失败==");

  67. }

  68. }
  69. }
  70. class Police extends Thread
  71. {

  72. House house;

  73. public Police(House house)

  74. {

  75. this.house = house;

  76. }

  77. public void getFired()

  78. {

  79. System.out.println("==警察成功救人==");

  80. }


  81. public void run()

  82. {

  83. try

  84. {

  85. while (true)

  86. {

  87. if (house.alert())

  88. {

  89. sleep(1000);

  90. getFired();

  91. break;

  92. }

  93. }

  94. }

  95. catch (Exception e)

  96. {

  97. System.out.println("==警察救人失败==");

  98. }

  99. }
  100. }
复制代码


做到这里,我们基本上已经成功的模拟了整个事件。那么,我们注意到几点:

1,无论警察还是消防员,都必须要存着那个房子的引用;

2,必须以死线程时时盯着那个房子。浪费了资源;

3,如果需要添加一个新房子,那么警察和消防员没有办法在不修改自身的情况下实现监视那个房子的行为。

4,这个虽然模拟了起火消防员灭火警察救人的行为。但是过程中,房子只是发生了起火的行为,并没有报告给警察和消防员。也就是说纯粹靠警察和消防员自觉监视房子。如果警察或消防员出了问题,那么房子就只能一直烧下去。。

那么我们希望做到什么样的程度呢?

1,房子主人可以自由选择需要负责自己安全的机构。比如可以选择警察,也可以选择医院,消防员等等。


2,不需要房子的安全负责人一直盯着房子,而是房子起火的时候房子的主人向安全机构报告。然后安全机构作出相应处理

3,消防员可以在不修改自身代码的情况下,被多个房子选择,也就是消防员可以不需要知道是哪个房子,只要房子在起火的时候报告给他他就会去灭火。

4,房子起火的时候,把自己的信息传送给消防员或警察。
第一次写这么长的-0-。。也算是个总结吧。。当中肯定有不恰当的地方。大家看了后希望指出来。
明天我会继续写第2篇。




[ 本帖最后由 弃天笑 于 2008-8-11 09:22 编辑 ]

事件监听机制1.rar

27.9 KB, 下载次数: 98

发表于 2008-7-23 20:38:55 | 显示全部楼层
建议你把文字直接贴出来,
能不用下载的尽量不用用下载的,
到时候我们更容易备份,而且有价值的东西也更容器被搜索引擎搜录。
发表于 2008-7-23 21:41:42 | 显示全部楼层
=。=文字你还搞成个附件??
 楼主| 发表于 2008-7-23 22:16:04 | 显示全部楼层
-0-。。。我用word写的,貌似复制出来格式有不对- -。。。
发表于 2008-7-23 23:08:15 | 显示全部楼层
- -!代码最好编辑一下
发表于 2008-7-23 23:20:28 | 显示全部楼层
其实这个文档不错的,
比较深入到事件编程的底层实现了——而不是简单介绍事件编程的用法。

建议是:
1.每个类单独给出,并以代码形式贴出。
2.代码增加一些注释,

将会有不少人对这个帖子很感兴趣,
我会推荐初学者想深入事件编程的同学来阅读的。
发表于 2008-7-24 19:54:16 | 显示全部楼层
很郁闷,我这里没有程序可以打开高版本的word文档。

说说我理解吧。
    无论是警察还是消防部队,只是一个实体,或者说是一个对象,在没有赋予他们相应的角色/权限的时候,他们都是普通人。赋予他们角色/权限就像是我们添加监听器的时候指定要程序做什么事情是一个道理。
警察、消防队都有专门的报警电话,他们不停在监控他们职责范围内的一切,当有警报的时候,他们在第一时间通知相关的职能部门(警察、消防队员)——这也就是我们的监听器,然后这些监听器就会执行他们的命令了。
    可以这样理解,警察、消防队员都是监听器,他们在监听他们职责范围内的信息,他们并不是主动监听——他们不需要取接电话,他们在宿舍里面呆着就行了,这里说他们“在监听”的意思是他们有空、就绪,从程序的角度来说,就是把这些监听器放到一个列表里面。
    当事件发生的时候,比如着火了,我们有两个职能部门在监听这个事件,也就是说我们有两个监听器列表。接电话的(我们就叫他们为“事件分发程序”吧)接到报警后,分别遍历这两个列表,通知到每一个的监听器对象(警察、消防队员),并且调用监听器对象的执行方法——run,那么事件就触发了一系列的动作。
发表于 2008-7-24 19:57:56 | 显示全部楼层
也就是说,事件监听模型最少包含五个对象:事件监听器(灭火的)、事件分发程序(接电话的)、事件源(着火的房子)、事件(着火了)、动作(防火)。
发表于 2008-7-24 22:21:28 | 显示全部楼层
原帖由 rodney 于 2008-7-24 19:57 发表
也就是说,事件监听模型最少包含五个对象:事件监听器(灭火的)、事件分发程序(接电话的)、事件源(着火的房子)、事件(着火了)、动作(防火)。

啊?我当时跟你们讲时好像不是用的灭火这个案例吧?呵呵。
我来归纳一下:
事件监听器(灭火的)、事件分发程序(接电话的)、事件源(着火的房子)、事件(着火了)、动作(习惯上称为事件处理器)(防火——消防员所做的事情)。
其实还有一个角色:事件触发者(广义的),就是负责去点火的那个家伙。

[ 本帖最后由 kongyeeku 于 2008-7-25 00:15 编辑 ]
发表于 2008-7-25 13:14:31 | 显示全部楼层
楼主辛苦了, 最好按楼上几位的意见编辑下代码及完善一下, 加精了
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

视频、代码、电子书下载
请关注"疯狂图书"公众号
QQ交流1群: 545923995  未满
微信群请扫二维码
QQ交流1群:
545923995
(未满)

小黑屋|手机版|Archiver|疯狂Java联盟 ( 粤ICP备11094030号 )

GMT+8, 2019-1-19 05:57 , Processed in 0.217533 second(s), 9 queries , File On.

快速回复 返回顶部 返回列表