ITPub博客

首页 > 应用开发 > IT综合 > OO 设计过程:细化问题定义 (转)

OO 设计过程:细化问题定义 (转)

原创 IT综合 作者:worldblog 时间:2007-12-14 09:47:51 0 删除 编辑
OO 设计过程:细化问题定义 (转)[@more@]

OO 设计过程:细化问题定义
关键是直接付款

Allen Holub
撰稿编辑,JavaWorld
2000 年 9 月

内容: 验证和细化 不要忽略明显的错误 倾听 sources">参考资料 关于作者
这个月我将继续细化上个月开始的关于 Bank of Allen 的教育软件的问题说明书。

当开始问题定义时,我通常是做下一步,建立一个词汇表。一般来说,对于熟悉该领域的人会马上明白术语的含义,因而不需要去定义它,但对于具有模糊含义的术语,或者在目前的问题中用在有限的范围内,这就需要专门来定义它。

在问题说明书中如 gotcha 是不妥当的。一个词不能指两个不同的事物,同时两个不同的词不能指同一件事物。要做到这一点,首先要建立词汇表。不需要定义该问题领域的术语。譬如,如果是会计方面的问题,您勿须定义 信用或者利率。然而,目前的问题是关于养育,所以象信用之类的术语需要精确定义。

词汇表对我们的主要目标也有帮助,它能确定关键问题层次的抽象。避免词汇表中的词和概念经常出现在问题说明书的正文中。譬如, 存折引入了术语交易。(交易的概念是重要的,虽然我没有立即认识到这一点。)

在词汇表中加入实现细节部分也是很有帮助的,它提供了记录这些细节的地方,就其本身而言,尽管它不是问题说明书的都具有的。那些通常归入功能性需求规范的东西常被放入实现细节。

以下是我的第一遍词汇表和实现细节。

idebar -->

词汇表

余额 当前在帐户中的货币金额。 银行 父母 贷方 由银行存入您的帐户,而不是您自己。 存款 将钱放入银行;增加您的余额。 利息 作为您一直把钱放入银行的报酬而给您的信用。利息是每天计算的,通过把信用按当前帐户余额的固定比例放入该帐户(“本金”)。如果利率是 10%/月,余额乘以 (.10/30) 就得到每天的利息。 存折 发生在某个帐户上的交易的作业记录和摘要信息。孩子们必须从银行得到存折。 取款 从银行取钱;降低您的余额。

实现细节
就其本身而言,这部分不是问题说明书的一部分。它只不过是我想起的清单,我把它与问题说明书放在一起。

  • 程序第一次运行时,父母可以为他们自己设置口令。从那以后,以父母亲登录必须要知道口令。父母亲在任何时候可以更改口令。
  • 更改利息率可以立即生效,但根本不影响以前的余额。(存折不一定(但可以)反映新的利率,该利率用于利率更改之日的存款,甚至是那天以前的。)
  • 小孩必须向银行申请存折。
  • 每次在给孩子们之前,存折要更新
  • 父母必须要有备份或银行的措施。这可以是简单文件拷贝或更加详细描述的说明。

验证和细化问题说明书
如果满意自己准备的合理的问题说明书,那么下一步做设计审查。我感激我的妻子 DJ,她是程序员并且是该方面的专家--母亲。她发现了各种各样小的语法性问题(我必须承认,你刚才所读的最初的陈述是我修订的),而且她发现了一个我没有意识到的严重缺陷。“你不能象那样计算利息”她指出。如果你仅仅根据一个月的天数来计算每月的利息,但是每天计算利息过于复杂,到月底你会得到一个很大的数目这要比你到月底再结算一次利息多的多。你在此所需要的是 名义的每月低于5%的利率,它将向你提供每月5%的有效利率。好吧。回到正文。

在当前问题中,出现了两个领域:养育,当然,从较小范围的角度讲的融资。我原以为我对费用了解的很多,但是很显然我错了。所以,我停下了设计,拣起了书本直到我完全了解了这方面的知识再继续设计下去。

这个问题本该出现得更早一些,如果我没有省略掉设计所必须的第二个步骤:在你对问题所属领域非常熟悉之后(第一阶段)和在开始建模之前(第三阶段),你必须与客户进行交谈以发现他们所需要的。我认为我不需要这样做,因为我已经是这方面的专家了-作为一个父亲。我错了。如果我与这方面的专家会谈过,一些并没有象我一样进入到设计的实质的人(例如我的妻子),在第一部分的利息问题上,我就可能做对。

不要忽略明显的错误
这儿有很多其他的例子,但最重要的是我称之为“浴室效应。”这一词干来源于几年以前我写给“ Dr. Dobb's Journal”一篇(未发表)文章开头的部分。“假设我们建造房子象我们做软件一样。” (我们都居住在如Winchester Mystery House一样的破房子里)。总之,到了文章的结尾,最后购房者第一次来看房子(在房子已经完全造好之后)。购房者带着迷惑的表情四处看了一圈,问“浴室在哪里?”

“浴室?”分包商说,“在说明当中没有浴室。现在把他们加上去会花很多钱;我们得浇注水泥,敲开墙。我们为什么不在房屋的后院盖一个呢?”

"这是什么意思‘它不在说明当中是什么意思’?”购房者结结巴巴的说,“谁会傻到设计房子而没有浴室?”

但是在软件设计中却是经常发生的问题。用户倒是不经常提及他需要的东西,而这些东西对问题来说都是很基本的。不是用户“对我隐瞒”正如许多程序员所说。这是因为设计者对问题所涉及的领域不够了解而提不出正确的问题。

不要仅仅点头 -- 倾听
当进行会谈的时候,倾听!不要打断。记住会谈中出现的每一件事情(那种会速记的人获益非浅),准确的记录下此领域专家的每一句话都是非常重要的。我曾经参加过许多会议,用户们说了几个小时,没有谁记录。随后,当用户离开后,没有谁能精确地记住讨论了些什么。在一部分程序员当中有一个不好的倾向,对用户所说的不加理会。都知道程序员们将用户对于问题什么的描述扭曲为程序员认为问题该什么的描述。他们将重新描述一些事情,将那些组成的问题涉及的领域翻译成更熟悉的语句,否则,他们所听到的就会产生扭曲和变化。经常,记住的是程序员们对问题的错误理解,而不是此领域的专家对问题的实际描述。

最后,记住大多数的用户都有过与那种自以为是的计算机人员相处很长的历史,那些人认为对于任何问题,他们比用户懂得更多。(由于认不清方向,城里人对农夫说,“你不是很聪明,是吗?”农夫回答道,“也许,但 我没有迷路。”)问题是许多用户过了一会儿就放弃了。如果程序员不认真倾听,为什么在交谈中就会有障碍?你将不得不打破这一系列的障碍。

一般而言,对于问题说明书的主要问题根本在于细节的级别是否属于它。通常,在问题实际上所涉及的领域当中,问题说明书的本身不会是科技术语。你得为了这个目标去参考教科书或字典。但在这,答案是“是的”因为固定利率和有效利率的区别在于他们不是实际问题领域的一部分(这是养育)。我们领域的专家是父母或会计师们。我们并不是发展一个运用于银行或建立一个试图运用于真正银行的模块的系统。这仅仅是为孩子们写的软件,不是关键的银行系统,所以我们不能采取我们部分专家关于如何计算利息的建议。利息的计算是问题定义的一个重要的部分,所以事实上它属于问题说明书。

问题说明书重点放在手边的问题是十分重要的。我们并不想在一段孩子的软件中解决“银行”的通病。在另一方面,我们也不想遗漏任何重要的细节。如果一般的读者(假设他们都是此领域的专家)需要一些信息以了解问题的陈述,然后就属于他们。如果这些资料是这个领域当中重要的一部分,我们不会加上去。在现在的情况下,如果我真正在写一个银行系统,我当然也就不会为定义“有效利率”犯愁了。因为我可以向这方面领域的专家请教这些知识。(由于同样的原因,设计者必须对问题所涉及的领域和此领域的基本术语有足够的了解。你不能设计一个会计应用程序除非你懂会计的一些知识-至少是一个聪明的外行。)

所以我找出一本傻瓜金融书,查出名义利息,并修改利息的定义为:

利息 作为您一直在银行存钱的报酬而给您的信用。利息被加入每天的余额中。

Bank of Allen 的运作如真正的银行一样,利息按照月份来计算。尽管如此,每天挣得的利息必须登记在存折上。这里的问题是根据每天计算的利息与每月计算的利息会产生不同的结果。

譬如,如果您开始在银行有 $100,利率是 10%,按照每 10 天计算的复利,在 10 天后,您帐户上将有 $110。

而另一方面,如果根据每天的复利计算,也就是将 10% 的利率平摊到每一天(1%/天)来计算,得到的结果会大于按每 10 天计算的结果。

第零天本金 $100.00 利息 $1.00 第一天本金+利息 $101.00 利息 $1.01 第二天本金+利息 $102.01 利息 $1.02 第三天本金+利息 $103.03 利息 $1.03 第四天本金+利息 $104.06 利息 $1.04 第五天本金+利息 $105.10 利息 $1.05 第六天本金+利息 $106.15 利息 $1.06 第七天本金+利息 $107.21 利息 $1.07 第八天本金+利息 $108.28 利息 $1.08 第九天本金+利息 $109.36 利息 $1.09 第十天本金+利息 $110.45

需要用两种利率解决这个问题:一种是孩子们知道的,另一种是银行内部用的。

有效利率
实际的利率,包含按复利计算的结果。假定月名义利率为5%,当按每日复利计算时,有效利率为5.12%。
名义利率
规定的利率,除去按复利计算的结果。

什么是有效利率,按每日复利计算,它是如何得到5%名义月利率?

N = 以小数表示的名义利率 (.05) P = 周期的天数(30天) E = 以小数表示的有效利率 公式: E = (1 + N/P)P -1 = .0512 利率 5%,按每日复利计算,与按每月复利 5.12% 计算,30 天后帐户上的余额数目是相同的。


当按每日复利计算时,名义利率为多少,可以得到有效利率为5%/月?

N = 以小数表示的名义利率 P = 周期的天数(30天) E = 以小数表示的有效利率 (.05) 公式: N = P * (E + 1)1/P -1 = .0488 利率 4.88% 按每日复利计算,与按每月复利 5% 计算,30天后帐户上的余额数目是相同的。


在一个周期内,如果只计一次复利,那么有效利率与名义利率是相同的。即,如果一个月计算一次利息,那么月有效利率与月名义利率是相同的。

简单地讲,银行公布的是有效利率:“您的月利率为 10%。这意味着如果您在银行存 $10 一个月,银行付给您 $1 的利息。”

由于利息是按每日复利计算的,每天计算利息必须要用名义利率(这样到了月底,由有效利率技计算的利息才能与之相一致)。譬如,假定一个月有 30 天,公布(有效)月利率为 5%,计算使用的(名义)日利率为 4.88%。如果您的帐户上初始有 $10,运用以下算法,您帐户上的将有 $10.50:

double balance = 10.00; int days_in_month = 30; double effective_rate = ->05; double nominal_rate = days_in_month * ( Math.pow(effective_rate+1, 1.0/days_in_month) -1); for ( int i = 0; i

现在看上去更合理,下面我们该做还没有完成的事情。这正是下个月专栏的主题。

参考资料

关于作者
Allen Holub 自1979年一直在计算机领域工作。他在许多杂志上发表过文章( Dr. Dobb's 月刊, 程序员月刊, Byte, MSJ,以及其它杂志),并且他是在线杂志JavaWorld的撰稿编辑。他有八本自己较赞赏的书,其中最新的一本( Taming Java Threads)讲述了 Java 线程的陷阱和缺陷。他一直从事设计和构建面向对象的软件很长时间了。当了 8 年 C++ 程序员之后,Allen 在 1996 年初放弃了 C++ 转向 Java 编程。他自从1982年一直在自己和为加利福利亚大学伯克利分校教编程(先是 C,然后是 C++ 和 MFC,现在教 OO 设计和 Java 编程)。Allen 提供 Java 技术和面向对象方面公共课程和专门培训。他还进行面向对象设计咨询和商业性 Java 编程。请访问 Allen 的网站 www.holub.com


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-993314/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    6241
  • 访问量
    2465354