如何真正找出面向对象设计中必须要做的事情?


12

首先免责声明:我真的不知道这个问题是否适合该网站,但是我仍然发现它不仅对我而且对其他初学者都是一个相关的问题。如果可以改善问题以使其适合此处,请指出int注释。如果不合适,也让我知道,如果可能的话,让我知道可以在哪里讨论,因为我没有找到任何好的论坛。

我在2009年学习PHP时就学会了编程。2012年晚些时候,我转到了C#和.NET。无论如何,编码不是问题,写下算法不是我的问题。我的实际问题是要知道必须编码什么才能达到要求,必须在哪里编码。

网络上提供的大多数课程都讨论了如何 -如何用某种语言编写代码,如何使用一些API集等。这不是我的意思。

这些年来,我读了很多有关一堆东西的信息:面向对象的分析和设计,设计模式,领域驱动的设计等等。例如,我了解SOLID原则,DDD的一些主要思想,例如聘请领域专家的必要性,开发无处不在的语言等。我敢说我的理论背景至少合理。

但是,当谈到练习时,我觉得自己是一场灾难。前一段时间,我需要继续开发已经由其他人开发的金融系统。这就是用C#和WinForms开发的那种“旧系统”。这是我第一次选择一个具有实际领域复杂性,业务规则等等的项目。

我承认,当我大多数时候收到要求时,我认为“这到底是怎么做的?” -我什至不知道如何开始着手研究需求以弄清楚必须做什么。我认为我的主要困惑是我必须编写什么代码,什么类,接口以及每条逻辑的去向,每件事必须在哪个类上。问题是我不知道从哪里开始。

大多数时候,经过很多思考,我最终想到了一些主意,但是我却永远不知道如何判断我的主意是否正确。

我的意思是我不认为这是一种理论上的不足,因为我说我已经阅读了有关软件体系结构和面向对象的一堆建议,但对确定实践中必须做的工作并没有多大帮助。

所以,我怎么能学会真正 做到面向对象的设计?我要学习的是:给定的需求知道如何开始在一个过程中进行工作,从而找出必须完成的工作以及每个代码所属的位置。我还如何学习判断我的想法是否正确?

我相信在这里不可能完全解释这一点作为答案。但是,我所寻找的可能是根据网站样式而定的答案,只是给出概述并指出一些参考资料(书籍,在线课程等),这些参考资料可用于扩展思想并真正学习这些知识。


1.您是否已经了解C#的所有基本概念,包括运算符重载与运算符重载之间的区别,什么是抽象类以及它与接口,封装,多态性有何不同等东西?首先了解这些内容对于全面理解C#中的OO是必不可少的。请参阅c-sharpcorner.com/technologies/oop-ood
罗伯特·哈维

2
2.用Winforms编写的较旧的应用程序除非经过适当的架构设计,否则往往会变成一团糟。关注点分离变得至关重要。参见winformsmvp.codeplex.com
罗伯特·哈维

1
确实没有一个过程。设计主要是要知道如何组织,这是经验带来的。SOLID原则是一个好的开始,但还远远不够,人们往往会迷失SOLID并忘记了为什么存在这些原则。
罗伯特·哈维

1
从头开始。需求就是问题。一个问题可能和“我们要开发下一个Stackexchange网站”一样大,也可能只有“我们希望下一个Stackexchange登录”这个问题。把一个大问题变成很多但更小的问题。总体而言,给自己一个机会去做“错误的”事情,并随着时间的流逝不断完善。
拉夫

1
我同时想对此进行
投票

Answers:


21

那么,我该如何真正学习面向对象的设计呢?我要学习的是:给定的需求知道如何开始在一个过程中进行工作,从而找出必须要做的事情以及每个代码所属的地方。我还如何学习判断我的想法是否正确?

首先,停止将面向对象的设计视为正确的想法。这就像认为英语是正确的。

面向对象的范例是不正确的。它具有某些优点和缺点。这是一个理想的选择。这不是我们唯一的。总比没有好,但肯定不是一切。

我已经编码了几十年了。我研究这些东西的时间几乎一直存在。我还在学习这意味着什么。专家们仍在学习这意味着什么。我们的整个领域还不到100年的历史。

因此,当您处理大量需求并生成满足要求的代码,但感觉自己编写的代码是悲惨的混乱时,您并不孤单。工作代码只是迈向出色代码的第一步。不仅有效,而且其他人也可以轻松阅读和理解的代码。需求变化时可以快速适应的代码。使您想坐下来说“哇,这很简单”的代码。

问题是我们没有获得全部酬劳。我们这样做是因为我们是专业人士。当老板不在时,我们必须做所有这些事情,因为总是有最后期限。但是我们想在5年后回来,对新手说:“哦,是的,我写了。仍然有效吗?酷。”

你怎么到那的?实践。不要接受任何基于信念的设计想法。有人不会说事件驱动设计如何简化该设计?不确定他们是否正确?使用观察者模式在家中建立自己的玩具项目。混乱了。尝试查找无法解决的问题。

读。题。测试。重复。

当您达到80%的人生经历时,您会和我一样困惑。

我承认,当我大多数时候收到要求时,我认为“这到底是怎么做的?” -我什至不知道如何开始着手研究需求以弄清楚必须做什么。我认为我的主要困惑是我必须编写什么代码,什么类,接口以及每条逻辑的去向,每件事必须在哪个类上。问题是我不知道从哪里开始。

我曾经有过同样的感觉。然后,我发现了重构的乐趣。在编写代码时愿意适应设计。尝试提前在纸上解决所有问题是困难的方法。编写可以被证明是错误的代码,证明它是错误的,并加以修复。


2
这是一个很好的答案。我从事编程已有15年了,我还要补充说,软件工程(我的专业)的整个领域都是“模糊的”-它是艺术与功能的混合体,并且取决于开发人员。我可以在纸上提出一个构架的想法,但是直到深入研究泥土,弄乱并找出有效的方法和无效的方法之前,我永远无法弄清楚OO设计的细节。
jropella

谢谢你的回答!因此,您的观点是:一旦我们有了至少一个解决方案来实现一个需求,并且该解决方案可以工作,我们就可以实现它,然后,当我们看到它与其他代码和其他需求的关系时,我们可以对其进行重构以使其更完善?但是在某些情况下,我有一些要求,但是我不知道如何开始。在这种情况下,您对如何开始有任何建议吗?有时,我认为最好的办法是讨论需求和可能的实现,但是我一个人工作。是否有一些欢迎此类讨论的论坛?
user1620696

2
首先,别再工作了。即使是一个笨拙的新手,也会让您放慢脚步,向他们解释事情要比这更好。其次,学习将需求分解为多个部分。继续这样做,直到您掌握了一些易于管理的东西。如果需要,可以在完全不同的环境中编写概念证明代码。只要做一些表达您对所需要内容的理解的事情即可。然后测试该表达式。你我发现你做了错误的假设。那很好。愿意改变他们。
candied_orange

1

在满足所有验收标准的同时,软件开发可以归结为按时,按预算交付工作软件。假设您已经做到了,那么代码的质量或其结构就是次要的问题。

当然,问题在于,编写新的新代码比维护旧代码要便宜得多,而且容易得多,因此请记住,真正的问题是可维护性,而不是过于依赖代码质量或体系结构。

通常,当与更改代码相关的成本,时间和风险相当低,以至于修正错误或对需求进行更改仍然具有成本效益时,代码就被认为是可维护的,并且通过实施这些更改,您不会永存“死亡螺旋”的代码熵”。

相反,如果您无法放心地更改或重构代码而没有严重的风险,即可能会破坏某些东西或花费过多的时间/金钱来确保没有任何问题被破坏,则代码被认为是无法维护的,即使用该代码所涉及的时间,成本和风险是与进行更改的好处相比,比例过高(例如,您的雇主或客户没有因为增加新功能,修复错误等而蒙受损失)

请记住,如果您在混乱区周围有足够的设施来保护自己免遭重大更改,那么即使是最令人讨厌的意大利面条混乱区也可以潜在地维护(尽管这种情况很少见)。意大利面条混乱的问题在于,保护其免受破坏变化的影响往往非常昂贵且效率低下-特别是如果您要追溯性地这样做。

确保编写可维护代码的最可靠方法就是同时(在合理可能的情况下)同时编写一套足够的自动化测试(同时还要充分利用可能提供的任何其他静态分析工具)。

您不需要特别遵循严格的开发方法(例如TDD / BDD)即可获得足够的自动化测试来重构。您只需要足够的代码来保护代码,以防将来意外更改。

如果您的代码包含在自动化测试中,那么您就可以放心地了解其设计和结构,因为您知道这些测试已覆盖了这些代码;您可以在以后主动进行重构,甚至将其丢弃并重新开始。

这就引出了如何编写易于测试的代码的问题;这通常是遵循SOLID原则的主要论点;实际上,遵守SOLID原则的代码的特点是编写单元测试的简便性和时间/成本效益。

当然,有时您也没有时间编写单元测试。但是,如果您在编写所有代码的同时记住“我如何为此编写自动化测试?”这个问题。(即使您实际上没有实施那些测试),您也可能已经找到了可以合理维护的设计。


1
我们从来没有时间编写自动化测试,但是我们总是有时间一遍又一遍地运行手动测试……
Nick Keighley

同样,我们从来没有时间第一次“正确地”和“干净地”编写代码,但是似乎有无数次的时间来不断地反复修改它,这是由于错误的但如此普遍的思维方式造成的。这个帖子。
扣篮赛

@Dunk我认为期望代码永远不要更改或重新访问是不现实的。单元测试实践和SOLID准则是关于鼓励实践的,当不可避免的情况发生时,这些实践导致代码易于更改且成本低廉-例如,某人发现了一个真正奇怪的模糊错误,而开发人员当时并未考虑这些错误,或者客户看到了解决方案和更改要求,甚至原始代码中都包含错误,因为开发人员只是人类;或是开发人员误解了需求,或者发现了以前未知的技术限制...
Ben Cottrell

1
@BenCottrell-我完全同意。始终需要重新检查代码。但是,由于这个原因,它导致人们指出花一些时间进行“前期设计”,并写一些“干净的代码”作为某种失败。他们使用“按时”和“预算内”的口头禅来证明不良代码/设计的合理性。您可以使用所有想要的“实践”,但是如果没有良好的设计和相对“干净的”代码,就不会买“容易更改且便宜的代码”。好的设计和“干净的代码”将是实际实现按时和按预算实现目标的副产品。
扣篮

@Dunk听起来您是在说许多开发人员只是不在乎代码质量,我认为通常情况并非如此。实际上,我认为存在两个更大的问题-首先,虽然开发人员可能是提供预算和截止日期估算的人,但估算很容易被证明是错误的。其次,项目利益相关者在时间/成本上拥有最终决定权,这意味着风险,预算和期限超过了技术关注点。在“绝对延迟/预算超支”或“潜在不良代码”之间进行选择时,我发现利益相关者经常选择后者。
本·科特雷尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.