你如何devise面向对象的项目?
我正在开发一个大型项目(对我来说),这个项目有很多类,需要进行扩展,但是我不确定如何规划我的程序以及类是如何交互的。
我在几个学期回到了OOD课程,并从中学到了很多东西。 比如编写UML,将需求文档翻译成对象和类。 我们也学习了序列图,但不知何故,我错过了讲座之类的东西,他们并没有真正坚持我。
在以前的项目中,我尝试过使用从课程中学到的方法,但是通常会以代码的forms结束,只要我可以说“是啊,看起来像我脑子里想的那样”,我不想挖掘泥土来添加新function。
我有一个史蒂夫麦康奈尔的代码完成 ,我不断听到是惊人的,在这里和其他地方的副本。 我阅读了关于devise的章节,似乎没有提供我正在寻找的信息。 我知道他说,这不是一个干净的过程,它主要是基于启发式的,但我似乎无法把他所有的信息都应用到我的项目中去。
那么在高级devise阶段(在开始编程之前),你需要做什么来确定你需要什么类(尤其是那些不是基于任何“真实世界对象”的类),以及它们将如何相互交互 ?
具体来说,我感兴趣的是你使用什么方法? 你所遵循的过程是什么,通常是一个好的,干净的devise,将密切代表最终产品?
我用于初始devise(获得类图)的步骤是:
-
需求收集。 与客户交谈,分析用例来定义软件应具有的function。
-
撰写个人用例的叙述。
-
通过叙述,突出名词(人,地点,事物),作为候选人类和动词(行为),作为方法/行为。
-
丢弃重复的名词并分解出常用的function。
-
创build一个类图。 如果您是Java开发人员,则来自Sun的NetBeans 6.7拥有一个允许进行图表绘制以及往返工程的UML模块,而且它是免费的。 Eclipse(一个开源的Java IDE)也有一个build模框架,但我没有经验。 您可能还想尝试ArgoUML,一个开源工具。
-
应用OOD原则组织你的课程(考虑常见的function,build立层次结构等)
我没有足够的声望发表评论(今天join),或者我只是评论斯科特·戴维斯的答案。 加上他所说的话:
-
在开始之前,确保你知道你的程序是什么。 你的计划是什么? 它不会做什么? 它试图解决什么问题?
-
你的第一套用例不应该是程序最终要做的所有事情的清单。 从你能想到的最小的用例开始,仍然捕捉你的程序的本质。 例如,对于这个网站,核心用例可能会login , 提出问题 , 回答问题 , 查看问题和答案 。 关于声望,投票或社区维基百科,没有什么关于你正在拍摄的东西的原始本质。
-
当你想出潜在的课程时,不要只考虑他们代表什么名词,而要考虑他们的责任。 我发现这是在程序执行过程中弄清楚类间是如何相互关联的最大的帮助。 像“狗是动物”或“小狗有一个母亲”这样的关系很容易。 找出描述对象间运行时间交互的关系通常比较困难。 程序的algorithm至less和你的对象一样重要,如果你已经详细说明了每个类的工作是什么,那么devise就更容易了。
-
一旦获得了最less的用例和对象,就开始编码。 尽可能快地获得真正运行的东西,即使它没有太多,可能看起来像垃圾。 这是一个起点,并会迫使你回答你可能会在纸上写下的问题。
-
现在回过头来select更多的用例,写下他们将如何工作,修改你的类模型,并编写更多的代码。 就像你的第一次剪辑一样,尽可能less的做,同时还可以添加一些有意义的东西。 冲洗并重复。
只是我的两分钱。 希望它是有用的。
当我有机会的时候,我通常使用我所说的“三迭代规则”。
在第一次迭代(或启动)中,我根据模型对象,algorithm以及期望的( 真正预期的,而不是预期的)未来方向来devise应用程序的总体布局。 我不写devise文件,但是如果我要协调多个人的话,当然需要粗略地描述这个过程,同时还要分析依赖关系和猜测所需的时间。 如果像我一样,你更喜欢更灵活的方法,尽量保持这个阶段的最低限度。 在某些情况下,需要强大的devise阶段,特别是当程序的逻辑知道所有事情都已知且真实时,以及计划在代码中的function之间进行很多交互时。 在这种情况下,用例或用户故事提供的是一个很好的高层次的想法,特别是对于GUI应用程序。 对于命令行应用程序,特别是图书馆,尝试编写“程序故事”,在其中对代码库进行编码,并检查它的外观。 这些程序完成后将成为你的图书馆的functiontesting。
在第一次迭代之后,您将更好地理解事物之间的相互作用,获得细节和粗略的位置,解决带耳塞胶带贴片的问题。 您已经准备好利用这些经验来改进,清理,打磨,分割太大,融合太碎片,定义和使用devise模式,分析性能瓶颈和非平凡的安全问题。 一般来说,所有这些变化对你写的unit testing都会产生巨大的影响,但是对functiontesting却没有影响。
当你完成第二次迭代时,你将会拥有一颗gem,经过充分testing,logging良好,devise良好。 现在你有经验和代码来做第三次迭代,扩展。 您将添加新function和用例来改进您的应用程序。 你会发现粗糙的地方,你最终会进入第四次迭代,类似于第二次迭代。 冲洗并重复。
这是我一般的软件devise方法。 它与螺旋式devise类似,只需短短的三个月的迭代,以及敏捷开发的元素,使您能够了解问题并了解您的软件及其应用领域。 当然,这是一个可扩展性的问题,所以如果应用程序如此庞大以至于涉及到数百个开发人员,情况就会比这更复杂一些,但最终我认为这个想法总是相同的。
所以总结一下:
- 在第一个练习中,你可以尝试一下并学习
- 在第二次迭代中,你清理你的产品并为将来做好准备
- 在第三次迭代中,您将添加新的function并了解更多信息
- 转到2
我所知道的最有趣的来源是Bertrand Meyer的第二版“面向对象软件构造的 D部分”。
D部分:面向对象的方法:很好地运用这个方法
19:方法论20:devise模式:多面板交互系统21:inheritance案例研究:交互系统中的“撤消” 22: 如何find类 ,23:类devise的原理,24:使用inheritance,25:有用的技巧,26:风格感,27:面向对象分析,28:软件构build过程,29:教学方法
有趣的是,第22章如何find这些课程可以在网上find 。
这是重复的,但完全正确的 – 了解你的数据。
对于面向对象,你的类应该描述信息的重要部分以及它们如何相互作用。
如果您有一个精心描述数据行为和生命周期的心智模型,您将可以轻松地布置您的课程。
这只是一个扩展:确切地知道你想要做什么。
尝试使用行为驱动的开发。 这将是很难打破你的旧习惯,但我发现,在现实世界中发展BDD真的是你最好的select。
大项目的问题是你不能监督组件之间的所有交互。 因此降低项目的复杂性至关重要。 类和序列图对于这个devise阶段来说太详细了。
首先尝试从更高的抽象层面思考。 考虑主要组件和它们的责任(与其他组件的接口),看一些架构模式的灵感(不,不是devise模式,这些是太低级别的MVC和多层是架构模式的例子)。 对于相当大的项目,这样的观点应该有3-5个组成部分。
只有这样,你才能放大某个特定的组件,并devise它。 现在我们处于devise模式和类图的层次。 尝试着重于项目的这一部分,如果您发现需要将责任添加到其他组件之一,只需将其添加到您的文档/待办事项列表。 不要浪费时间思考这个问题的含义,他们的改变太快了,回顾一下devise是否更加扎实。
在这一点上,您不需要完全devise每个组件,但是有一段代码实现未实现的组件接口并生成简单而有用的响应可能是明智的。 这样,您可以一次开始(和devise)一个组件,并对其进行合理的testing。
当然,当新的组件完成时,你应该先testing它们是如何(以及如果)在彼此融合之前进行的。
在很短的时间内:采取面向对象和信息隐藏的原则,并把它拉上一个新台阶!
PS:在devise时做很多素描,就像真正的build筑一样!
PPS:尝试从不同的angular度来处理这个问题,在盒子外面思考(虽然盒子可能是要走的路),与同事讨论可能对此非常有用…而且在午餐时间你可以谈论一些事情。
devise模式
创造性的devise模式
单例 – 确保只创build一个类的一个实例,并为该对象提供一个全局访问点。
Factory(工厂方法的简化版本) – 创build对象而不向客户端公开实例化逻辑,并且通过公共接口引用新创build的对象。
工厂方法 – 定义创build对象的接口,但让子类决定实例化哪个类,并通过一个公共接口引用新创build的对象。
抽象工厂 – 提供用于创build相关对象族的界面,而不显式指定其类。
Builder(生成器) – 定义创build对象的实例,但让子类决定实例化哪个类,并允许更好地控制构build过程。
原型 – 指定使用原型实例创build的对象种类,并通过复制此原型来创build新对象。
行为devise模式
责任链 – 避免将请求的发送者附加到其接收者,从而使其他对象也可以处理请求。 – 对象成为链的一部分,请求从一个对象发送到另一个对象,直到其中一个对象处理它为止。
命令 – 将一个请求封装在一个对象中,允许不同请求的客户参数化,允许将请求保存在一个队列中。
解释器 – 给定一种语言,定义一个语法表示,连同一个解释器一起使用该解释器来解释语言中的句子/将一个域映射到一种语言,一种语言映射到一种语法,另一种语法映射到一种分层的面向对象的devise
迭代器 – 提供一种方法来访问聚合对象的元素,而不暴露其底层表示。
介体 – 定义一个封装一组对象如何交互的对象。 中介者通过使对象避免明确相互引用来促进松耦合,并且可以让你独立地改变他们的交互。
观察者(Observer) – 定义对象之间的一对多依赖关系,以便当一个对象改变状态时,所有依赖对象都会被自动通知和更新。
策略 – 定义一系列algorithm,封装每一个algorithm,并使它们可以互换。 策略可以让algorithm独立于使用它的客户端。
Template Method(模板方法) – 在操作中定义algorithm的骨架,将一些步骤推迟到子类/ Template Method让子类重新定义algorithm的某些步骤,而不用改变algorithm的结构。
Visitor – 表示要对对象结构的元素执行的操作/ Visitor允许您定义新操作而不更改其操作的元素的类。
空对象 – 提供一个对象作为缺less给定types的对象的代理。 /空对象模式提供了智能无所事事的行为,隐藏了协作者的细节。
结构devise模式
适配器 – 将类的接口转换为客户端期望的另一个接口。 / Adapter使类可以一起工作,否则由于接口不兼容而无法工作。
桥 – 将对象组成树结构来表示部分 – 整体层次结构。 /复合让客户统一处理个别对象和对象的组合。
复合 – 将对象编写到树结构中以表示部分 – 整体层次结构。 /复合让客户统一处理个别对象和对象的组合。
装饰者 – dynamic地将其他职责添加到对象。
享元 – 使用共享来支持大量的对象,这些对象的一部分内部状态是共同的,另一部分状态可以变化。
纪念品 – 在不违反封装的情况下捕获对象的内部状态,从而提供了在需要时将对象恢复到初始状态的方法。
代理 – 为对象提供一个“占位符”来控制对它的引用。
我在真正的项目中使用的技术,合理的成功是责任驱动devise,受Wirfs-Brock的书启发。
从顶层的用户故事开始,与同事们一起在白板上画出他们所暗示的高层互动。 这让你首先了解大模块是什么; 和一个或两个高水平的CRC卡像玩,你应该已经稳定了主要组件的列表,他们做了什么,他们如何相互作用。
然后,如果任何责任很大或很复杂,那么通过展开模块内部的交互,为每个由更高级别的交互所识别的主要操作,细化这些模块,直到您拥有足够小又简单的对象。
知道何时停止是一个判断问题(只有经验)。
我会build议你使用BlueJ和ActiveWriter来学习,并且对对象有很好的理解。 这本书推荐也是一个很好的资源。
维基百科 :
BlueJ是Java编程语言的集成开发环境,主要用于教育目的,也适用于小规模软件开发。
另外它使用UML,对于我来说,理解关于build模对象的几件事是一个很好的资源。
替代文字http://www.ryanknu.com/ryan/bluej.png
ActiveWriter是一个模型实体和关系的工具,它也生成代码,很容易做出改变。 这将节省您的时间,并为敏捷开发是非常合适的。
替代文字http://altinoren.com/activewriter/Images/Introduction_1.png
我想这里的答案应该是非常不同的,取决于这个家伙的现实世界的经验。
如果你只有一两年的工作经验,那么你必须明白的一点是:你如何达到你真正了解你的数据的位置,并明确你所要做的事情?
是的,如果你已经在现实世界工作了5年以上,那么你可以select任何一种软件开发过程模型或技术。
但是,只有阅读书籍才能获得经验。 你应该在一个良好的领导下,在一个好的团队中学习。
如果这是不可能的,那么你应该自己做。 开始迭代编码一个可能非常讨厌的代码,学习你的错误,倾倒一切,编码一个更好的,等等。
你会学到很多关于你的代码库的知识。 工具是工具,他们不会教你什么。
恐怕这不是人们喜欢听的答案。 无论如何,让我说出我的意见。
面向对象应该被看作范式之一,而不是高级范式。 OOP对于解决某些问题非常有用,比如开发一个GUI库。 它也符合大型软件公司的软件开发风格 – 一个由devise师或build筑师组成的精英团队在UML图表或其他类似的媒介中devise软件devise,而不那么开明的开发团队将该devise转化为源代码。 如果你单独工作,或者与一个非常有才华的程序员团队一起工作,面向对象程序devise(OOP)没有什么好处 那么,最好使用支持多种范例的语言,并且能够帮助您快速创build一个原型。 Python,Ruby,Lisp / Scheme等都是不错的select。 原型是你的devise。 然后你改进。 使用最好的范例来解决手头的问题。 如果需要,优化用C语言或其他系统语言编写的扩展的热点。 通过使用这些语言之一,您还可以免费获得可扩展性 ,不仅在程序员级别,而且在用户级别。 像Lisp这样的语言可以dynamic地生成和执行代码,这意味着用户可以通过编写小代码片断来扩展应用程序,而这些代码片段使用软件自身编码的语言! 或者,如果您select使用C或C ++编写程序,请考虑为Lua等小语言embedded解释器。 公开作为用该语言编写的插件的function。
我认为,大多数情况下,OOP和OOD创build的软件是过度devise的受害者。
总而言之,我写软件的首选方法是:
- 使用dynamic语言。
- 用这种语言写出devise(原型)。
- 如有必要,使用C / C ++优化某些区域。
- 通过实现语言本身的解释来提供可扩展性。
最后一个function使软件能够轻松适应特定用户(包括我自己!)的要求。
只要引用http://www.fysh.org/~katie/computing/methodologies.txt
在RUP的核心是一个小区域,你必须使用面向对象的devise人才….如果你没有他们,就像拥有一个跑100米的方法。
第一步:快速写下跑步第二步:制定跑马圈计划第三步:购买非常紧密的莱卡短裤第四步:运行真的非常快第五步:先交叉线“
这就是第4步,这是艰难的。 但是如果你把重点放在1,2,3和5上,那么没有人会注意到,那么你可能会花费大量的资金来销售这种方法,那就是运动员认为有一些“秘密”是100米亚军结束
你问了很多作者用来写书的问题。 有很多的方法,你应该select一个似乎“最漂亮”给你。
我可以推荐Eric Evans出版的“Domain Driven Design” 。 此外,检查网站dddcommunity.org 。
- 学习和掌握devise模式。
- 接下来,了解域驱动devise
- 之后,学习需求收集
我在几个学期回到了OOD课程,并从中学到了很多东西。 比如编写UML,将需求文档翻译成对象和类。 我们也学习了序列图,但不知何故,我错过了讲座之类的东西,他们并没有真正坚持我。
-
你知道第3步。你需要掌握它。 我的意思是,通过大量的练习使它成为你的第二天性。 那是因为你学习的方法,就是反对我们以前的方式。 所以你需要真正掌握它。 否则,你总是会发现自己回到原来的做事方式。 这就像testing驱动过程,很多java开发者在尝试几次之后放弃它。 除非他们完全掌握它,否则这只是他们的负担
-
写用例,尤其是替代课程。 备用课程占我们开发时间的50%以上。 通常当你的PM给你一个任务时,例如创build一个login系统,他会认为它是直接的,你可以花一天时间完成它。 但是他从不考虑你需要考虑的事项,1.如果用户input了错误的密码,2.如果用户input错误密码3次,3.如果用户没有input用户名等等。你需要把它们列出来,并显示给你的下午,要求他重新安排最后期限。
首先 – devise应该来自你的灵魂。 你必须感觉到你的每一根纤维。 我通常在开始做任何事情之前,先走两三个月,走上街头(真的)。 思考。 你知道,散步是一个很好的冥想。 所以它可以让你集中精力。
其次 – 仅在自然对象层次存在的地方使用OOP和类。 不要“人为地”把它搞砸。 如果不存在严格的层次结构(就像在大多数业务应用程序中一样) – 进行过程/function,或者至less仅将对象用作具有隔离访问器的数据容器。
最后 – 尝试阅读: 创造性思维的algorithm
我使用testing驱动devise(TDD)。 首先写testing实际上有助于引导你devise一个干净而正确的devise。 见http://en.wikipedia.org/wiki/Test-driven_development 。
学习devise模式 。 过去两年来,OOP是我个人的革命。 得到一本书。 我会build议你这一个:
首先devise模式
这是在Java中,但它可以扩展到任何语言。
老实说,一个好的步骤将回头看stream程图和序列图。 有很多好的网站,告诉你如何做到这一点。 我发现当我想知道程序需要input,计算和输出的内容时,如何将程序分解成类,这是非常宝贵的,每一步都可以分解成程序的一部分。
正如您在devise您要编写的软件时遵循的工作stream程中回答的那样?
一个有用的技术是将你独特的问题描述与你在现实世界中find的东西联系起来。 例如,你正在模拟一个复杂的医疗保健系统,将风暴世界。 有没有什么例子可以用来模拟这个模型?
确实。 观察副药店的运作方式或医生的房间。
将您的域名问题降到您可以理解的地步; 你可以涉及的东西。
然后,一旦域中的“玩家”开始显现出来,并且开始为代码build模,则select“提供者 – 消费者”build模方法,即您的代码是模型的“提供者”,而您是“消费者”。
关于这个领域和高层次的理解是任何devise的关键部分。
如果你有项目领域的专业知识,你会像说银行业务一样工作。 结构化对象很容易,而且您知道每隔一天这些增强function是如何来的。
如果您没有这方面的专业知识与具有专业知识的人合作,并将这些想法转化为技术细节。
如果您对如何构build项目devise感到困惑。 盲目追随“实用程序员”一书。 我以前也是这样,试着读那本书的一章。 您将看到不同之处,它将改变您作为软件开发人员的想法。
在devise类结构的冒险中,我注意到从编写一些伪代码开始非常有帮助。 这意味着:我开始在最高层“编写”应用程序代码的一些通用片段,并使用它来发现出现的元素 – 事实上,我作为一个程序员 – 将使用的元素。 这是devise模块的总体结构及其相互作用的一个非常好的起点。 经过几次迭代后,整个结构开始看起来更像一个完整的类的系统。 这是devise部分代码的一种非常灵活的方法。 您可以将其称为面向程序员的devise。