zytbwu
BlogJava
首页
新随笔
联系
聚合
管理
随笔 - 4 文章 - 4 trackbacks - 0
<
2007年3月
>
日
一
二
三
四
五
六
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
Eclipse相关(1)
JAVA语言
XML(1)
设计模式(1)
随笔(1)
随笔档案
2007年3月 (4)
文章分类
Eclipse相关
Java
Linux
专业知识
相关转载
设计模式
收藏夹
界面
设计模式
Design Patterns
eclipse-plugins website
J道:Java解决之道
Ebook
Eclipse
Good Blog
TerryLee技术专栏
很好的一个blog,里面的设计模式讲得很详细,很不错
老赵点滴
师兄的blog,有很多地方要向他学习。
Good IT WebSite
CSDN
Java
Java开源大全
挺不错的一个网站,是个可以从中学习一下别人是怎么写代码的
中文JAVA技术网 -- 为Java爱好者服务
挺不错的一个网站,是个可以从中学习一下别人是怎么写代码的
Linux
搜索
最新评论
1. re: XmlBuddy插件配置过程
学一下。呵呵。
--alexhi
2. re: Observer模式 学习笔记1
学校真好!
--Druze.libo
3. re: Observer模式 学习笔记
呵呵,睡不着而已。
今天学校要注册了,明天就要开学了~
--冰雪荒原
4. re: Observer模式 学习笔记
这么早起来写东西啊!真是勤奋 啊!向你致敬!
--lang
阅读排行榜
1. Observer模式 学习笔记1(1201)
2. XmlBuddy插件配置过程(714)
3. 开博第一篇(171)
4. 初学XML(139)
评论排行榜
1. Observer模式 学习笔记1(3)
2. XmlBuddy插件配置过程(1)
3. 开博第一篇(0)
4. 初学XML(0)
Observer模式 学习笔记1
GOF的设计模式中是这样描述Observer模式的意图(intent)的:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
我自己的理解是:
Observer模式定义了一种多个对象之间的一对多的相互依赖关系,当一个对象的状态发生改变时,其他与之有关系的对象“看上去”都要相应采取行动。
试着用Observer模式写了一些代码,模拟灌篮比赛,运动员每次灌完之后,评委为他们打分。
在这里Player是Subject;
ChinesePlayer和USPlayer是ConcreteSubject;
Rater是Observer
DunkRater是ConcreteObserver
Player中的endPlaying方法就是Player的行为或(引起观察者行为的)事件。
Rater中的rate方法是观察者的响应行为。
1
public
abstract
class
Player
2
{
3
protected
String name;
4
protected
int
height;
5
public
String getPlayerName()
6
{
7
return
this
.name;
8
}
9
10
public
int
getPlayerHeight()
11
{
12
return
this
.height;
13
}
14
private
ArrayList
<
Rater
>
raterList
=
new
ArrayList
<
Rater
>
();
15
16
public
void
addRater(Rater rater)
17
{
18
this
.raterList.add(rater);
19
}
20
21
public
void
removeRater(Rater rater)
22
{
23
this
.raterList.remove(rater);
24
}
25
26
protected
void
askForRating()
27
{
28
for
(Rater rater :
this
.raterList)
29
{
30
rater.rate();
31
}
32
}
33
34
/**/
/*
35
这里不写成dunk()是为了以后的扩展之用,因为可能现在开发的是灌篮比赛,
36
以后再加入其他类型的比赛,比如投篮。
37
可以采用策略模式来完成。
38
*/
39
public
void
play()
40
{
41
//
some code to describe play
42
}
43
44
public
void
endPlaying()
45
{
46
askForRating();
47
}
48
}
49
50
public
class
ChinesePlayer
extends
Player
51
{
52
public
ChinesePlayer(String name)
53
{
54
this
.name
=
name;
55
}
56
57
public
void
play()
58
{
59
System.out.println(
this
.name
+
"
have a power dunk
"
);
60
}
61
}
62
63
public
class
USPlayer
extends
Player
64
{
65
public
USPlayer(String name)
66
{
67
this
.name
=
name;
68
}
69
70
public
void
play()
71
{
72
System.out.println(
this
.name
+
"
have a highflyer dunk
"
);
73
}
74
}
75
76
public
abstract
class
Rater
77
{
78
protected
String name;
79
public
abstract
void
rate();
80
}
81
82
public
class
DunkRater
extends
Rater
83
{
84
85
public
DunkRater(String name)
86
{
87
this
.name
=
name;
88
}
89
90
public
void
rate()
91
{
92
//
TODO 自动生成方法存根
93
int
score
=
(
int
)(Math.random()
*
8
)
+
2
;
94
System.out.println(
this
.name
+
"
:
"
+
score);
95
}
96
97
}
98
99
public
class
DunkGame
100
{
101
public
static
void
main(String[] args)
102
{
103
Rater rater1
=
new
DunkRater(
"
Kobe
"
);
104
Rater rater2
=
new
DunkRater(
"
Jordan
"
);
105
106
Player player1
=
new
ChinesePlayer(
"
Yao Ming
"
);
107
Player player2
=
new
USPlayer(
"
James
"
);
108
109
player1.addRater(rater1);
110
player1.addRater(rater2);
111
112
player2.addRater(rater1);
113
player2.addRater(rater2);
114
115
player1.play();
116
player1.endPlaying();
117
118
player2.play();
119
player2.endPlaying();
120
}
121
122
}
123
某一次打印出的结果如下:
Yao Ming have a power dunk
Kobe: 4
Jordan: 4
James have a highflyer dunk
Kobe: 7
Jordan: 5
几点讨论:
1)在Player(Subject)中的那个raterList是否可以把private改为protected?
我觉得改了不好,因为不应该把“用什么数据结构、何种方式保存Rater(Observer)”暴露给用户。(客户程序员,他们可以扩展Player这个抽象类),否则就违背了封装性。
2)从面向对象的几个原则来看Observer模式
a)把变化的部分封装起来:
我们可以很好地扩展Player和Rater两个部分,彼此没有过多影响。因此Observer模式在方面做的还是很好的。
ConcretePlayer与ConcreteRater这间的联系就是ConcretePlayer维护着一个注册过的现有的Rater(Observer)的列表(这个列表的实现方式对于负责扩展地程序员应该是透明的),ConcretePlayer不知道它的监听者具体是什么类型,只知道它们实现了Rater(Observer)的接口。
b)面向接口编程而不是面向实现
在客户主程序中,只出现了三个具体的类,这样的问题可以通过工厂模式解决。
值得注意的一点,也是Head First in Design Patterns中对于这条原则的一个解释:
一直以来我们所说的面向对象设计中很重要的一条原则--面向接口编程,再加之继承存在的种种问题,容易使人产生错觉:使用关键字interface。
实际上这条原则的一个等价的说法是
“面向SuperType编程”
。这里的SuperType的意思是接口或者超类。
因此用abstract class并没有违反这样的原则,反而是遵守了。
3)语义上与实现上是否是相反的
我不明白是翻译问题还是我自己没懂,总觉得GOF的描述中“自动”二字和“观察者”会给读者带来误解。
原因如下:
Observer模式描述的是这样的一种情况:
当一个Subject的状态发生变化或被触发了一个事件的时候,在这个Subject上注册的对象要依据这样的变化或事件做出相应的反映,这些对象然后被称之为Observers。
按照GOF的说法,从语义上来说应该是Observer主动响应了这个行为。
但在实现上应该是Subject调用Observer的这个响应行为,这就是我上面所说的“看上去”主动响应,实际上是被动地被Subject调用。
因此Observer和自动不免给人带来误解,站在Subject的角度上给这个模式取名,叫作通知者模式也许更好。
这个例子,以后会重构,将其他模式应用上去。在网上学习的过程中,知道Observer模式和责任链模式、MVC模式会有组合,但我现在还没有学到,就先写这些吧。
posted on 2007-03-04 06:50
冰雪荒原
阅读(1201)
评论(3)
编辑
收藏
所属分类:
设计模式
FeedBack:
#
re: Observer模式 学习笔记 2007-03-04 08:38
lang
这么早起来写东西啊!真是勤奋 啊!向你致敬!
回复
更多评论
#
re: Observer模式 学习笔记 2007-03-04 10:18
冰雪荒原
呵呵,睡不着而已。
今天学校要注册了,明天就要开学了~
回复
更多评论
#
re: Observer模式 学习笔记1
2007-03-04 16:42
Druze.libo
学校真好!
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理