你如何设计面向对象的项目?
我正在开发一个大型项目(对我来说),它将有很多类,并且需要具有可扩展性,但是我不确定如何规划我的程序以及类需要如何交互。
我在几个学期回到了OOD课程,并从中学到很多东西。 比如编写UML,并将需求文档翻译成对象和类。 我们也学习了顺序图,但不知何故,我错过了讲座或其他东西,他们并没有真正坚持我。
在之前的项目中,我尝试过使用从课程中学到的方法,但通常会以代码的形式结束,只要我可以说“是的,看起来像我脑子里想的那样”,我不想挖掘垃圾来添加新功能。
我有一份史蒂夫麦康奈尔的Code Complete,我不断在这里和其他地方听到它的惊人之处。 我阅读了关于设计的章节,似乎没有提供我正在寻找的信息。 我知道他说这不是一个切割和干燥的过程,它主要基于启发式,但我似乎无法将他的所有信息都应用到我的项目中。
那么在高级设计阶段(在开始编程之前)你要做什么来确定你需要什么类(尤其是那些不是基于任何'真实世界对象')并且它们将如何相互交互 ?
具体来说,我对你使用什么方法感兴趣? 你所遵循的过程是什么,通常是一个好的,干净的设计,将密切代表最终产品?
我用于初始设计(获取类图)的步骤如下:
需求收集。 与客户交谈并分析用例来定义软件应具有的功能。
撰写个人用例的叙述。
通过叙述并突出名词(人,地点,事物),作为候选类和动词(动作),作为方法/行为。
丢弃重复的名词并分解出常用的功能。
创建一个类图。 如果您是Java开发人员,Sun的NetBeans 6.7拥有一个允许进行图表绘制以及往返工程的UML模块,并且它是免费的。 Eclipse(一个开源的Java IDE)也有一个建模框架,但我没有经验。 您可能还想尝试ArgoUML,一种开源工具。
应用OOD原则来组织你的课程(考虑常见的功能,构建层次结构等)
我没有足够的声望发表评论(今天加入),或者我只是对斯科特戴维斯的回答发表评论。 增加他必须说的话:
在开始之前,确保你知道你的程序是什么。 你的计划是什么? 它不会做什么? 它试图解决什么问题?
你的第一套用例不应该是程序最终要做的所有事情的清单。 从你能想到的最小的用例开始,它仍然捕捉你程序的本质。 例如,对于该网站,核心用例可能会登录,提出问题,回答问题并查看问题和答案。 关于声望,投票或社区维基百科,只是您拍摄的原始内容。
当你想出潜在的课程时,不要仅仅根据他们所代表的名词来考虑他们,而应该考虑他们的责任。 我发现这是在程序执行过程中弄清楚类间如何相互关联的最大帮助。 很容易想出诸如“一只狗是一只动物”或“一只小狗有一只母亲”的关系。 通常很难找出描述对象之间运行时间交互的关系。 你的程序算法至少与你的对象一样重要,如果你已经详细说明了每个类的工作是什么,那么它们更容易设计。
一旦你获得了最少的用例和对象,就开始编码。 尽可能快地获得尽可能多的东西,即使它没有太多,可能看起来像垃圾。 这是一个起点,并会迫使你回答你可能在纸上写下的问题。
现在回过头来选择更多的用例,写下它们的工作方式,修改你的类模型并编写更多的代码。 就像你的第一次剪辑一样,尽可能少地进行,尽可能增加一些有意义的东西。 冲洗并重复。
只是我的两分钱。 希望它是有用的。
当我有机会时,我通常使用我所说的“三次迭代规则”。
在第一次迭代(或启动),我设计的应用程序的总体布局根据模型对象,算法,和预期( 实料,没有也许预期)未来的发展方向。 我不写设计文件,但是如果我必须协调多个人,当然需要粗略地描述这个过程,并且需要分析依赖关系和猜测所需时间。 如果像我一样,你更喜欢更敏捷的方法,尽量保持这个阶段最小化。 在某些情况下,需要强大的设计阶段,特别是当程序的逻辑知道所有事情都已知且真实时,以及计划在代码中的功能之间进行很多交互时。 在这种情况下,用例或用户故事提供的是一个很好的高层次思路,特别是对于GUI应用程序。 对于命令行应用程序,尤其是图书馆,尝试编写“程序故事”,在该程序中您针对要开发的库进行编码并检查其外观。 这些程序在完成后将成为您的图书馆的功能测试。
在第一次迭代之后,您将更好地了解事物如何相互作用,弄清楚细节和粗略的位置,并通过带耳塞的胶带补丁解决问题。 您已经准备好利用这些经验来改进,清理,擦亮,划分太大的内容,融合过于分散的内容,定义和使用设计模式,分析性能瓶颈和非平凡的安全问题。 一般来说,所有这些变化都会对你编写的单元测试产生巨大的影响,但不会影响功能测试。
当你完成第二次迭代时,你将拥有一颗宝石,经过充分测试,记录良好,并且设计良好。 现在你有经验和代码来做第三次迭代,扩展。 您将添加新功能和用例来改进您的应用程序。 你会发现粗糙的点,你最终会进入第四次迭代,类似于第二次迭代。 冲洗并重复。
这是我对软件设计的一般方法。 它与螺旋式设计类似,只需短短的三个月的迭代以及敏捷开发的元素,可让您了解问题并了解您的软件及其应用领域。 当然,这是一个可扩展性的问题,所以如果应用程序如此庞大以至于涉及数百个开发人员,情况会比这更复杂一些,但最终我认为这个想法总是相同的。
所以总结一下: