蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 597, 评论 - 4064, 引用 - 276

导航

关于

这里是我的技术Blog,下一代CSDN社区Blog在 http://blog.csdn.net/ghj1976/

标签

每月存档

最新留言

  • re:学习笔记:7种结构型设计模式简单对比
    <p>最新在家创业系统 ----刚从国外引进,市场巨大。 ----在家可经营所有国家生意,事业规模宏大。 ----不需求人与说服;不用放厚脸皮去推销。 ----极小投资;零风险;成...
    by jackielongteng(注册) on 2009/6/14 13:43:56
  • re:作用域
    <p>☆                    &deg;∵☆       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...
    by jackielongteng(注册) on 2009/6/14 13:03:25
  • re:Html标签嵌套对展示性能的影响
    <p><strong>所有的浏览器都按照你提到的浏览器解析Html规则来解析嘛?</strong></p>
    by Cola(注册) on 2009/6/12 23:07:28
  • re:Html5
    <p>目前来说,HTML5还只是一个梦想,呵呵:)</p>
    by 开心就好(注册) on 2009/6/11 16:31:54
  • re:多线程与SqlConnection.Close
    <p>好服月租型IT服务台,与你共成长! 月租型ITSM软件,注册即可免费体验! 详情请登录官方网站:<a href="http://www.servicezon.co...
    by qzhibo(注册) on 2009/6/3 15:14:21
  • re:多线程Singleton单件模式
    <pre><span style="color: #0000ff;">//Another way public</span> <sp...
    by Yaojian(注册) on 2009/4/22 14:02:35
  • re:Thread.Sleep(0)
    <p>学习了~</p>
    by shuitong888(注册) on 2009/4/8 14:29:24
  • re:Html标签嵌套对展示性能的影响
    <p>DIV固然好 但IE6,7,8 firefox,safari ....做美工的人要累死.</p>
    by ryq1(注册) on 2009/4/3 14:16:25
  • re:用.net 编码实现朗读文本的方法
    <p>我第一次 按键时 能听到声音,但是第二次按键时,没反应。网页一直在 loading.&nbsp;是什么原因?</p>
    by tracytang949(注册) on 2009/3/27 7:01:09
  • re:information_schema.routines与sysobjects
    <p>用sys.procedures多好。</p>
    by luke(注册) on 2009/3/16 16:45:49
  • re:SQL Server 2005 配置发送邮件
    <p>&lt;A href="<a href="http://www.3rt.info">http://www.3rt.info</...
    by ives007(注册) on 2009/2/26 16:47:00
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:45:08
  • re:推荐 Gemini 这个bug管理工具
    <p>你好!首先非常感谢推荐使用Gemini,这段时间在使用Gemini,有些问题想请教以下。</p> <p>1.Create Issue 以后,设置了Visib...
    by CowboyRyan(注册) on 2009/2/20 15:32:06
  • re:虚机搭配NLB负载平衡时碰到"没有接口可用于安装新的群集"的解决方案
    <p>google newsid</p>
    by iads(注册) on 2009/2/13 17:25:07
  • re:try catch 与线程
    <p>确实是这样的。因为异常机制本质上是堆栈操作,而各线程的堆栈是独立的。</p>
    by st_szr(注册) on 2009/1/21 9:46:05
  • re:try catch 与线程
    <p>没啥啊,线程就是新启动了一个,当然异常不会影响到原有的线程了。</p> <p>你应该在线程里面合适的位置写上自己的捕获代码就行了。</p>
    by laozizhu(注册) on 2009/1/19 16:33:21
  • re:我的2008,征服天堂
    <p>蝈蝈,可惜我帮不了你啊!</p>
    by laozizhu(注册) on 2009/1/19 16:25:45
  • re:try catch 与线程
    <p>呃&hellip;&hellip;是这样的。可怎么处理呢?</p>
    by Anders Liu(注册) on 2009/1/19 11:58:05
  • re:我的2008,征服天堂
    <p>博主是不是去了师部 做了侦查营长呢?</p>
    by huobazi(注册) on 2009/1/9 14:15:33
  • re:我的2008,征服天堂
    <p>@ghj1976:看来真的危机了</p>
    by 开心就好(注册) on 2009/1/9 10:17:37
  • re: 网络带宽的单位
    不过传输的时候,往往还有压缩。
    by luke(匿名) on 2008/12/15 11:00:21
  • re: 网络带宽的单位
    除10不仅仅是为了方便,在传输中,往往加上控制位,所以一个字节往往需要10Bit.
    by 关门放狗(匿名) on 2008/12/13 16:01:30
  • re: 多缓存并存
    对跨进程甚至跨服务器缓存的性能比较怀疑,进程通信和跨服务器通信代价不菲。即使有已有进程外数据可用,如果考虑在进程做份缓存,定期再进程间同步是否更佳?
    by jinglecat(匿名) on 2008/12/12 18:00:05
  • re: 网络带宽的单位
    好像还有一个为了方便换算,厂家使用的是 除10的处理方式的说法:于是100Mb/sec = 100M / 10 = 10M Byte/sec 所以我通常都是用除10而不是除8来做运算的。
    by kentliu(匿名) on 2008/12/11 11:38:55
  • re: 网络带宽的单位
    又不是大S小s
    by luke(匿名) on 2008/12/10 12:04:50

广告

 

最近在做CSDN新论坛的设计,我就走了OO设计上的死牛角了。一度头大的不知所以然。下面来看我所走的弯路,希望对大家有所帮助。

 

先说功能需求

我们有这样的需求:
论坛由很多具体论坛组成。对于某个具体论坛来说,它是下述功能的组合,可能是其中一个功能的组合,也可能是其中几个功能的组合,不过确定组合后,有哪些组合就很少会发生变化,这些功能包括:

积分制、勋章制、贴图、帖链接、可以发投票帖 等等......

每个具体论坛,上述功能组合都可以不同。

 

简单来看我走的死牛角:

以论坛帖子类的设计为例。

不论用上述那些功能组合,一个帖子类,当然会有一个基类,这个基类包含最最基本的帖子信息,比如帖子编号、标题、发帖者等等。

对于 A 论坛,它选择了使用积分制功能,则A 论坛的帖子类应该还包括一个帖子分数的字段来记录跟积分制有关的信息。

对于B论坛,它选择了使用贴图功能,则B论坛的帖子类应该还包含一个字段,来记录相关的图片链接。

对于C论坛,它选择了同时使用积分制和贴图功能,则C论坛的帖子类应该还包含上述两个字段。

………………….

我们会有很多种组合。非常非常多。

 

如果我们用每个论坛实现一个派生自基类帖子类的子类,问题会是:组合太多了。而且以后丰富功能的时候,每新增一个功能,需要新增的子类会不可想象。

如果使用一个超级类,把所有功能都封装到一个类来。每个功能涉及的属性都有默认值。

则会给这个类的使用者带来很多意想不到的问题:

因为这个类相关的内部逻辑可能是开发人员A设计的。而使用者会是开发人员B

某种情况可能会需要对这个超级类的123三个属性给值。另外一种情况则…..  之前有多少种组合,这里可能就有多少种情况。

让开发人员B熟悉这么多种组合,很容易啥时候就出问题。复杂,太复杂了。

……………………………………

 

上面就是我陷入的死牛角。

 

解决方法:

一、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑数据库的设计,看你数据表是如何设计的。你完全可以把数据表的结构映射到OO的设计上来。

二、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑界面的设计,然后从界面的功能转到OO的设计上来。

 

这里不是说OO不好,而是由于还没有对这方面的抽象习惯过来,通过对整个流程的思考,会帮助你构造好的OO类。

就象模式一样,也是别人经过很多实践得出来的,一般都叫做refactor to patterns,即对自己的编码反复重构,最后这些编码就成了模式,或与模式相似。

不要硬套OO或者模式设计。

 

对于我这里的设计,

数据库上存储帖子信息,显然是可不管你每个论坛使用了哪些功能,而是认为所有功能你都使用了,对于没使用的功能,则认为对应的字段使用的是默认值。

不论用那种组合论坛,因为他们界面展示上完全不一样,每一套功能组合,我们都需要提供一套页面模版和接受读取参数功能来处理。这样其实组合方式并不是多得不可接受,仍然是可接受的。

 

想明白上述两点,设计就很简单的,就不会过度设计,钻OO设计的牛角了。

打印 | 张贴于 2006-03-13 11:33:00 | Tag:.net 编程心得  技术随笔  网站开发管理相关内容

留言反馈

#上周技术关注:第16届JOLT大奖获奖名单公布 编辑
BOOKS GENERAL
Jolt Winner: Prefactoring by Ken Pugh (O'Reilly)

Productivity Winners:
* Innovation Happens Elsewhere: Open Source as Business Strategy by Ron Goldman, Richard P. Gabriel (Morgan Kaufmann)
* Producing Open Source Software: How to Run a...
2006-03-20 13:13:00 | [匿名用户:曾登高]
#re: 千万别钻 OO设计上的死牛角 编辑
Decorator类似的设计模式用.NET的委托列表实现很方便,这也是曾经考虑的方案但是这种方式实际上是管理同层次上的一些函数。但实际的功能总要和具体的数据结构联系起来的,这些数据怎样组织。其实好多时候c的解决方法值得被oo弄晕头脑的人学习。
2006-03-15 10:21:00 | [匿名用户:neverBorn]
#re: 千万别钻 OO设计上的死牛角 编辑
这样困难我也曾遇到过,有很多不同原子功能实现,具体对象由这些功能组合而成,但组合的可能很多。功能间的依赖关系复杂。让我至今很头疼。oo很适合处理类层次纵深的问题,但是如何组织同层次不同分支的对象呢?
2006-03-15 10:00:00 | [匿名用户:neverBorn]
#re: 千万别钻 OO设计上的死牛角 编辑
借鉴IE,Dom模型,每一个html标签对应一个对象,每个标签又有自己的属性,IE根据标签实例化对象,画页面视图.

借鉴windows shell扩展,一种文件类型对应一个扩展,也有通用的扩展,windows用注册表保存插件信息



"数据库上存储帖子信息,显然是可不管你每个论坛使用了哪些功能,而是认为所有功能你都使用了,对于没使用的功能,则认为对应的字段使用的是默认值。"

我觉着这样设计数据库好像不合理,难道我新增一项功能,就的添加一个字段,我想采用一个字段,这个字段存储xml,然后根据xml实例化插件
2006-03-15 09:44:00 | [匿名用户:Rover]
#re: 千万别钻 OO设计上的死牛角 编辑
to:steeven

新社区复杂的一个地方,就是可以按照你说的方式展示,同时旧有BBS的方式仍然可以展示。


至于复杂性。没办法,
1是必须考虑性能问题。
2是必须考虑灵活的功能
2006-03-14 18:47:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
不就是添加删除修改弄的这么复杂干什么
2006-03-14 17:55:00 | [匿名用户:1]
#re: 千万别钻 OO设计上的死牛角 编辑
TO:steeven
bbs毕竟不是文档中心,bbs重在参与过程,发言的多,总结的少。
2006-03-14 15:57:00 | [匿名用户:小陆]
#re: 千万别钻 OO设计上的死牛角 编辑
偶想说说信息的组织分类问题。现在所有的论坛,都有这个毛病。
1. 一个topic只能发到一个分类里面,实际上有是涉及到多个分类的。比如jdbc的问题可能属于j2ee/mysql
2. 分类组织过于笼统。分类应该细致的象搜索引擎一样,没有的分类可以马上建立。利用ajax可以很容易实现
3. 一个topic可以是投票,blog,提问。。。有树形reply分支。

实现以上3点,信息检索就相当方便,也更有价值。
2006-03-14 14:50:00 | [匿名用户:steeven]
#re: 千万别钻 OO设计上的死牛角 编辑
可以参照一下outlook的设计,ms网站上有outlook宏开发的文档,对outlook的对象模型有详细描述。
2006-03-14 13:02:00 | [匿名用户:小陆]
#re: 千万别钻 OO设计上的死牛角 编辑
二十个类就有二十张表 是夸张的说法。实际谁也不会这么干。
2006-03-14 11:51:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
我觉得问题在于你在写用例的时候没有把用例进行充分地细化。。。。。。。。。。。。


对我也有同样感觉。
但是,做用例的话,之前也这么做过。最后又花时间,进度有慢。
而且更关键的是,功能变化太快。比如目前推荐WEB2.0的思想,那很多功能就发生变化了。

给自己网站做东西。可没法用合同定义好,只实现那些功能。
头大呀。而且进度卡的狠紧。
2006-03-14 11:50:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
我用的Blog程序serendipity,它的做法是插件可以修改数据库,在现有的表里添加字段。做一个插件基类,任何插件扩展于此类,然后将插件的名字注册到主程序的配置文件中,主程序按照顺序依次执行各个插件。理论上来讲,它的速度跟你直接操作数据库没有太大区别,因为这些插件是调用主程序提供的函数来获取数据库内容的。


这个方法不错,甚至可以做一个客户端插件配置程序,一个客户端选择插件后,动态生成需要的数据结构。

反正插件选择后,改动不会很大。

2006-03-14 11:46:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
大哥,你不会是想把所有子论坛的帖子都放在一张表里吧?

我觉得应当是一个子论坛一张表,但是所有子论坛有公共属性

我的回复:

CSDN 目前有300多个大小论坛。
新社区会同时开通用户组论坛和帖吧功能。

新的CSDN的论坛上十万很正常。
2006-03-14 11:41:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
装饰模式的一个缺点是:
装饰模式会使一个系统带有“大量的小对象”,对于维护代码的程序员来说,他们看起来都差不多,维护起来很头疼。

另外,
每个论坛的可组合模式很多,多的不计其数。

前面说的“不论用那种组合论坛,因为他们界面展示上完全不一样,每一套功能组合,我们都需要提供一套页面模版和接受读取参数功能来处理。这样其实组合方式并不是多得不可接受,仍然是可接受的。”

并没有说对。

正确的应该是组合是多的不计其数。但是具体到某个功能,比如发帖页面。
可能几十种组合用的发帖模版都是一个模版。

可能会出现下面的情况:
A 论坛是 aa\bb\cc\dd 功能的组合。它的发帖页面用的是1号发帖模版,列表页面是用的 3号列表模版。

B 论坛是 ww\dd\ee\rr 功能的组合。它的发帖页面用的是1号发帖模版,列表页面是用的 3号列表模版。

C 论坛是 oo\ww\e\r\d 功能的组合。它的发帖页面用的是1号发帖模版,列表页面是用的 1号列表模版。

..................

组合会非常多。但是具体到某个功能,则这个功能的模版是有限个数的。

可能最后会有10套发帖模版、10套列表模版。 但是组合模版可能就有1000种。
2006-03-14 11:39:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
首先我觉得作者的解决方案也是可以的。毕竟解决问题更加重要。作者提出的不要“钻牛角尖“这个说法非常重要,我也经常钻,白钻不厌。不过最近有点收敛了,哈哈!
OO设计的一个重要原则是:能够使用组合就尽量不用继承。根据这个原则来看应该优先考虑是不是有利用组合原则的解决方案,比如说前面一个朋友提到的装饰模式(Decorator)可能就比较合适。
第二个问题是,是不是说一个类就该对应一张表呢?就像作者说的,二十个类就有二十张表?我觉得不一定,从关系模型到对象默想必然会有一个映射,是否能够或者说应该以一对应都是要具体问题具体分析的。
不知道我的观点是不是正确,很高兴和大家讨论。

yujianqiu@gmail.com
2006-03-14 10:44:00 | [匿名用户:Steven]
#re: 千万别钻 OO设计上的死牛角 编辑
我觉得问题在于你在写用例的时候没有把用例进行充分地细化,对于非功能需求也没有做足够的考虑,所以你在做oo设计的时候发现了不少问题。

我不赞成你提的说法。
2006-03-14 09:23:00 | [匿名用户:James]
#re: 千万别钻 OO设计上的死牛角 编辑
连空格都不处理,这积怨深了 :)

ForumBase------------------->ForumMetadata
 | *             + UseImage
 | |             + UseGrade
 | |             + UseLink
 | |             + other capabilities....
 | |
 | +------------------------>IForumPlugins
 |               |
 |               +----------> ImagePlugin
 Forum(没有任何功能)      +----------> GradePlugin
2006-03-14 09:12:00 | [匿名用户:tiaoci]
#re: 千万别钻 OO设计上的死牛角 编辑
大哥,你不会是想把所有子论坛的帖子都放在一张表里吧?

我觉得应当是一个子论坛一张表,但是所有子论坛有公共属性

功能的组合可能会很多,但是,子论坛并不多啊,

只要创建论坛时通过一个配置创建就可以了,我还是支持OO方式

把论坛的定义当作元数据,写代码时只按照元数据去操作论坛就可以了

结构如下,请参考

ForumBase------------------->ForumMetadata
| * + UseImage
| | + UseGrade
| | + UseLink
| | + other capabilities....
| |
| +------------------------>IForumPlugins
| |
| +--------------> ImagePlugin
Forum(没有任何功能) +--------------> GradePlugin
2006-03-14 09:08:00 | [匿名用户:tiaoci]
#re: 千万别钻 OO设计上的死牛角 编辑
解决楼主的问题正是OO的强项,建议复习一下设计模式
2006-03-14 08:27:00 | [匿名用户:Dreamaster]
#re: 千万别钻 OO设计上的死牛角 编辑
先搞个ER图,然后再画UML,你就不会走这么多弯路了。
2006-03-13 21:51:00 | [匿名用户:Project D]
#re: 千万别钻 OO设计上的死牛角 编辑
统统不care,大哥你就赶快把它release吧.. 04年就说在改了,都快两年了
2006-03-13 21:04:00 | [匿名用户:sunmast]
#re: 千万别钻 OO设计上的死牛角 编辑
你的问题好像就是装饰模式要解决的问题
2006-03-13 20:34:00 | [匿名用户:Goodspeed]
#re: 千万别钻 OO设计上的死牛角 编辑
光看你的描述,如果嫌不考虑存储,只考虑OO,你为什么不把帖子类都具有一个“功能s”的collection呢?然后功能再去做派生不是更好吗?
2006-03-13 18:02:00 | [匿名用户:wing]
#re: 千万别钻 OO设计上的死牛角 编辑
我很同意这个观点,设计是为需求服务的。单方面地追求设计的完美是不必要的。不过,联系蝈蝈俊本文的需求,我认为利用OO设计应该是能够解决的。方法就是采用装饰模式。
对于论坛的帖子,一些基本的属性可以定义为共同的基类。然后我们可以为每一种方式的帖子,建立新的类,这个类应该是细粒度的,便于利用装饰模式进行组合。例如为积分建立一个专门的子类,为贴图建立一个专门的子类,利用装饰模式可以非常方便的建立各自的组合类。即使未来有扩展,这种装饰的方式仍然是可行的。
2006-03-13 16:07:00 | [匿名用户:wayfarer]
#re: 千万别钻 OO设计上的死牛角 编辑
从你的描述来看,是先有设计,把类的关系设计好,再去写代码。

这样的过程已经有了方法论的总结:RUP。RUP强调用例驱动建模,而用例。也就是用户需求的UML描述,在你的案子里可以理解为你说的“先考虑界面的设计,然后从界面的功能转到OO的设计上来”。


2006-03-13 14:07:00 | [匿名用户:wyatt]
#re: 千万别钻 OO设计上的死牛角 编辑
我用的Blog程序serendipity,它的做法是插件可以修改数据库,在现有的表里添加字段。做一个插件基类,任何插件扩展于此类,然后将插件的名字注册到主程序的配置文件中,主程序按照顺序依次执行各个插件。理论上来讲,它的速度跟你直接操作数据库没有太大区别,因为这些插件是调用主程序提供的函数来获取数据库内容的。
2006-03-13 13:13:00 | [匿名用户:Jason Cui]
#re: 千万别钻 OO设计上的死牛角 编辑
性能重要,有些设计很漂亮,但是层次过多,严重影响性能。。比如java里面一些框架。。
2006-03-13 12:24:00 | [匿名用户:coolmenu]
#re: 千万别钻 OO设计上的死牛角 编辑
恩 为何OO 为何不OO 很多人搞不清楚,web站点重要是性能,我顶你的做法。
2006-03-13 12:12:00 | [匿名用户:笨猫猫]
#re: 千万别钻 OO设计上的死牛角 编辑
另外,如果做成插件方式,我需要做的插件太多了。

比如可以回复就可以认为是一个插件。
帖子高亮显示又是一个插件。
积分制也是一个插件。
贴图也是一个插件。

每个插件涉及到一个表的话。
20个插件,就要增加20个表。
那再多呢???
2006-03-13 11:51:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
忘了说一点:

我考虑的优先级,
第一是性能,
第二才是丰富的功能。
2006-03-13 11:47:00 | [匿名用户:ghj1976]
#re: 千万别钻 OO设计上的死牛角 编辑
数据库上存储帖子信息,显然是可不管你每个论坛使用了哪些功能,而是认为所有功能你都使用了,对于没使用的功能,则认为对应的字段使用的是默认值。

照这样子来看的话,如果你以后要增加新的功能怎么办?为什么不做成插件机制?
2006-03-13 11:46:00 | [匿名用户:Jason Cui]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.1.8