合金枪头.net
努力用简单的语言解释复杂的技术
博客园
首页
社区
联系
订阅
管理
随笔-112 评论-610 文章-5 trackbacks-16
老师讲的抽象工厂,错了一点点
他也有讲错的时候,虽然只是一点点,但还是被我抓到了,呵呵。而且通过对错误地方分析可以知道,错因是他对
OOD基本
原则的理解以及对
Abstract Factory
的理解似乎还不是十分到位。
看得出,他讲《设计模式》的蓝本是英文版的
GoF
《
Design Patterns
》,课件上都是清一色的英文,对每一个
DP
的介绍模式也都是按照
GoF
那本书来的。但是他今天在讲到抽象工厂局限性的时候,用红色字体打出:
difficult to ... new kinds of objects
(
p.s.
原话记不清了)
然后解释说:抽象工厂的局限性就在于当有新的产品线
3
需要加入系统的时候,不但要新建继承自
AbstractProcuctA
的
ProductA3
类,新建继承自
AbstractProcuctB
的
ProductB3
类,“
这倒没有什么”
,而且还要新建一个集成自
AbstractFactory
的
ConcreteFactory3
,“
这就不行了”
。从他的语气中可以知道他认为新建类,特别是要新建一个具体工厂是“
不好”
的。
然而就我目前对
DP
的理解,情况却不是这样的。当有产品线
3
需要加入系统时,正好是抽象工厂显示威力的时候。新增加的三个派生类
ProductA3
、
ProductB3
和
ConcreteFactory3
很好的展示了抽象工厂模式符合“
开放-封闭原则”
的特点
——
新的需求没有对原有的设计和结构,特别是
AbstractFactory
和
AbstractProductX
接口做任何的修改,只是对现有系统进行了扩展,就实现了新的需求。而对“
增加新的产品线
/
族
/
系列”
这个轴线上的需求变化的应对自如也正是抽象工厂的力量所在。
那么对于
GoF
书中的那句“
difficult to ... new kinds of objects”
怎么理解呢?
抽象工厂的局限性应该是当需求变化的轴线在于“
增加组成系统的新产品
/
对象”
的时候,就力不从心了。
这里就拿老师上课举的例子来说明。他的例子是构建一个迷宫游戏(
Maze Game
),组成迷宫(
Maze
)的基本元素有三个
——
房间(
room
)、墙壁(
wall
)和门(
door
)。游戏分为不同的
难度等级,比如
easy/normal/hard
,对应于不同的难度,房间、墙壁和门是不同的,比如
hard
模式的门可能是带有密码锁的。其实这个例子看起来并不十分恰当,因为通常应该觉得迷宫的难度等级应该按照其内部的复杂度来划分,而不是按照他的这种方式来划分,这个暂且不管,就先用他的划分方式吧。
场景,比如丛林迷宫、楼房迷宫等等。在这些不同的场景下,房间、墙壁和门的风格当然也是不同的,所以这里应用抽象工厂是一个合适的选择。
//
AbstractFactory
public
abstract
class
MazeFactory
{
abstract
Room CreateRoom();
abstract
Wall CreateWall();
abstract
Door CreateDoor();
}
//
ConcreteFactory1
public
class
JungleMazeFactory : MazeFactory
{
public
override
Room CreateRoom()
{}
public
override
Wall CreateWall()
{}
public
override
Door CreateDoor()
{}
}
//
ConcreteFactory2
public
class
BuildingMazeFactory : MazeFactory
{
public
override
Room CreateRoom()
{}
public
override
Wall CreateWall()
{}
public
override
Door CreateDoor()
{}
}
//
AbstractProductA
public
abstract
class
Room
{}
//
AbstractProductB
public
abstract
class
Wall
{}
//
AbstractProductC
public
abstract
class
Door
{}
//
ProductA1
public
class
JungleRoom : Room
{}
//
ProductA2
public
class
BuildingRoom : Room
{}
//
ProductB1
public
class
JungleWall : Wall
{}
//
ProductB2
public
class
BuildingWall : Wall
{}
//
ProductC1
public
class
JungleDoor : Door
{}
//
ProductC2
public
class
BuildingDoor : Door
{}
现在如果需求发生变化,需要一种新的迷宫场景,比如海底迷宫(
SeabedMaze
),而迷宫的基本组成元素仍然是房间、墙壁和门,那么我只需要对原有系统做如下
扩展
:
//
ConcreteFactory3
public
class
SeabedMazeFactory : MazeFactory
{
public
override
Room CreateRoom()
{}
public
override
Wall CreateWall()
{}
public
override
Door CreateDoor()
{}
}
//
ProductA3
public
class
SeabedRoom : Room
{}
//
ProductB3
public
class
SeabedWall : Wall
{}
//
PruductC3
public
class
SeabedDoor : Door
{}
然后
client
就可以生成通过传入
SeabedMazeFactory
的对象实例来创建这个海底场景的迷宫了,原有的逻辑都可以不动,这样就算是再来几个空中迷宫、地下迷宫什么的,只要是迷宫的基本组成三要素
——
房间、墙壁和门不变,我就可以通过不断的对现有系统进行扩展来达到目的,哈,太完美了。
但是,如果这时需求朝着另一个方向变化
——
迷宫中需要加入新的元素,比如陷阱、楼梯、地道……
——
那就完蛋了。如果还是单单通过扩展现有系统就达不到目的了。原因就在于
ProductA
、
ProductB...
增加了,而
AbstractFactory
,或者说是
MazeFactory
中只有
CreateRoom()
、
CreateWall()
和
CreateDoor()
抽象方法,而如果要加入对陷阱、楼梯、地道……的支持,则必须要修改
MazeFactory
这个
AbstractFactory
的接口,而这显然是不希望看到的,也是违背“
开-闭原则”
的。
抽象工厂的局限性就在于此。
那
GoF
的话说错了吗?请注意,人家说的可是“
new kinds of objects”
,而不是“
new families of objects”
,一字之差,含义完全不同。老师把
GoF
的意思理解成了后者,而后者不但不是抽象工厂的劣势,反而恰恰是其优势所在。前者才真正是抽象工厂的软肋。
这里又想到一个事情,我还是觉得GoF那本书不太适合做入门读物,更不太适合做教材,但是这学期的课上老师推荐的书只有三本,第一本就是这个,唉~~我觉得这本小册子会挡住很多对DP有热情但又缺乏实践经验的初学者的。
posted on 2006-03-30 16:31
合金枪头
阅读(1778)
评论(8)
编辑
收藏
所属分类:
Design Patterns
评论:
#1楼
2006-03-31 00:57 |
aspnetx
支持
我们学校的老师绝对比你说到的还白痴
讲面向对象的时候会给你两中感觉:一听着好累,而,好想扁人
回复
引用
查看
#2楼
2006-03-31 01:08 |
wen3062 [未注册用户]
我们学校的老师根本不讲~
回复
引用
#3楼
2006-03-31 01:31 |
jackyrong的世界
看<<head first design pattern>>吧
回复
引用
查看
#4楼
2006-03-31 03:14 |
bengxia
个人感觉设计模式通过讲课确实很难说清,还是得静下心来实践+思考。有点只可意会,不能言传的悬乎。学习优秀的代码能掌握不少,还是不要刻意去搬套。
另外,楼上的小弟未成年吧。
回复
引用
查看
#5楼
2006-03-31 03:57 |
POLARIS
只是明白别人讲的不是,真正的理解。
真正的理解,需要实践,需要发表,需要很多...
回复
引用
查看
#6楼
[
楼主
] 2006-04-02 03:47 |
合金枪头
@aspnetx
我们的这个老师课讲的还是很不错的,但估计他也没有在实际工程中广泛的应用DP,这也可以理解。不过其他更垃圾的讲课的人我这也有不少,纯粹是骗课时费。
@jackyrong的世界
《Head First》那本书我手里有电子版,印刷版我一直在犹豫到底买不买,也曾去过书店,但是由于出版社太怪异——东南大学——我们这里的书店基本都不跟他合作,所以也只能作罢。而且DP的书我也有好几本了,暂时就先看这些吧,特别推荐的是《Design Patterns Explained》现在刚出了第二版。
@bengxia
你说的对,DP是从实践中来的经验,自然也应该回归实践。讲课+听课的方式一直就是我比较反感的信息传播方式,授课者的表达方式可能就已经把知识打了一次折,听课者在理解的时候又打了一次折,所以最终的效率是很低的,特别是这种以实践为基础的课。
p.s.原来你楼上的苍蝇已经轰走
@POLARIS
能体会到这种级别的老师(他也算是我们学校的金牌教授了,这课也是他们学院研究生的核心课,DP只是其中的一个专题)在这种层面上的一点点偏差应该也算是“真正的理解”的一个阶段吧:)
回复
引用
查看
#7楼
2006-09-08 02:42 |
wayne1017
貌似你听到这个错误以后就走人再也不去听他的课了吧?呵呵
回复
引用
查看
#8楼
[
楼主
]
2006-09-08 10:00 |
合金枪头
@wayne1017
-_-!这都被你发现了……
回复
引用
查看
许可协议:
知识共享署名-非商业性使用-禁止演绎 3.0 Unported
hits
Contact me via
<
2006年3月
>
日
一
二
三
四
五
六
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
8
与我联系
发短消息
搜索
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的参与
我的新闻
最新评论
我的标签
留言簿
(27)
给我留言
查看留言
我参加的小组
GIS.DeveloperUnion
开源GIS学习小组
我参与的团队
WebGIS(0/905)
GIS.DeveloperUnion(开发者联盟)(0/777)
我的标签
性能
(1)
Python
(1)
循环
(1)
随笔分类
(119)
.NET(7)
Design Patterns(4)
GIS(22)
MIS(9)
德意志见闻(8)
读书笔记(5)
非技术(39)
技术评论(14)
实用技术(1)
数据库(9)
通信(1)
网格
文章分类
(5)
.NET
ArcSDE影像数据管理(2)
Oracle10g GeoRaster影像数据管理(3)
技术
CSDN
博客堂
友情链接
StudentMIS驻非洲大使
在非洲翱翔的斑鸠
ViewPoint
有前途的师弟
梦里花开
我的最有创意的同学,朋友,战友
积分与排名
积分 - 63996
排名 - 691
最新评论
1. re: [通知]最后一篇“非技术”
@kykl-__-!帅哥,你要匿名说啥呀?留言的限制是作者设定的...昨晚从意大利回来,这次山爬的还是比较爽的,呵呵,要是你在就更好了。刚才看了泰晤士报新给的全球大学排名,居然把TUM排在78,北大排...
--合金枪头
2. re: [通知]最后一篇“非技术”
唉,博客园不能匿名留言,scheisel
--kykl
3. re: [通知]最后一篇“非技术”
去了
--kykl
4. re: [通知]最后一篇“非技术”
@kykl
呵呵,现在blogger国内也能访问了,非技术部分可以去
看,最近还是在写滴>_-
--合金枪头
5. re: [通知]最后一篇“非技术”
靠,那我不来了。。。。
--kykl
阅读排行榜
1. 倒退的历史?——某MIS项目手记(2):为什么不用存储过程?(3701)
2. 面向对象,面向服务(3243)
3. tiff/tfw, jpg/jpgw坐标文件的格式(2564)
4. 倒退的历史?——某MIS项目手记(1):“切五花肉”式的分工(2452)
5. 微软的"云"从三年前开始(1875)