如何练习更好的面向对象编程?[关闭]


82

我从事面向对象语言的编程已经有很多年了,但是我秘密地看着同事们羡慕的一些事情。他们中的许多人似乎都有一些我没有的内在的OO本能-无论我多么努力。我已经阅读了所有有关OO的好书,但似乎仍然无法破解。我觉得这个家伙付出了110%的职业足球运动员的心,但是却没有天赋。我很茫然,想换职业-我该怎么办?


1
也许我应该读坏书。
2009年

3
您正在使用什么语言?您可以列出一些“好”书的书名吗?
Achim

8
让我们看看您非常担心的一些代码。我敢打赌,我会发现比原来差10倍的东西。
斯宾塞·鲁波特

4
仔细

3
尽管我是面向对象程序设计的忠实拥护者,但我要强调的是,您可以使用其他语言/技术来从事软件行业。OO技能!=编程技能,尽管OO变得如此普遍。我希望其他人也会同意...
Grundlefleck

Answers:


127

我要说的是,不那么关注OO编程,而更关注OO设计。拿起纸和铅笔(或者可能是UML建模工具),然后离开屏幕。

通过练习如何设计系统,您将开始对对象关系有一种自然的感觉。代码只是设计的副产品。绘制图并以纯非代码形式对应用程序建模。有什么关系?您的模型如何相互作用?甚至不用考虑代码。

一旦您花了时间设计...,然后将其转换为代码。您会惊讶于一个好的OO设计可以这么快地编写代码。

经过大量的设计实践,您将开始看到可以模块化或抽象化的公共区域,并且您将在设计和代码方面得到改善。


2
我感谢您的想法..!
Basheer Kharoti

我同意用笔和纸比使用显示器效果更好!
艾林

那么下一个问题可能是:“如何练习OO设计?!?” 我认为OO不应是任何人使用编程来实现现实世界目标的第一次经验。只是我的两分钱。
aderchox

38

最简单的方法是学习诸如SOLID,DRY,FIT,DDD,TDD,MVC等概念。当您查找这些首字母缩写词时,它将导致您陷入许多其他困境,一旦完成阅读工作,您应该拥有对什么是更好的面向对象编程有很好的了解!

SOLID播客:http : //www.hanselminutes.com/default.aspx? showID=168 ,http : //www.hanselminutes.com/default.aspx? showID=163

SOLID细分:http : //butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

干:http//en.wikipedia.org/wiki/Don%27t_repeat_yourself

散客:http//www.netwellness.org/question.cfm/38221.htm

DDD:http//dddcommunity.org/

DDD要求阅读:http : //www.infoq.com/minibooks/domain-driven-design-quickly

TDD:http : //en.wikipedia.org/wiki/Test-driven_development

MVC:http//en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

是的,卷起袖子并编码始终是一个好主意。尽自己最大的能力来做一个小项目。然后从上面阅读一篇文章。然后重构您的代码,以满足您刚刚阅读的内容的需求。重复进行直到您将代码重构为地狱为止。最后,您不仅应该了解OO的全部内容,还应该能够解释为什么它很重要以及如何第一次获得它们。学习如何重构也是获得良好代码的关键。现在的事情明天不正确。


但是,并非所有的首字母缩略词都必然与面向对象的设计有关。(即DRY原则在任何类型的编程语言中仍然很重要)
wds

我同意。但是它们仍然适用于适当的面向对象编程。
安德鲁·西默

18

太多的人认为编码首先是对象,最后是编码。

您可以阅读所有想要的书,但这不会教您如何以面向对象的方式进行思考-需要实践和某种方法。

  1. 以下是一些对我有帮助的方法:当您不在工作中并且思想开放时,可以通过将所有事物视为一个对象来进行 练习。不要看这些对象,不要想知道如何对它们进行编程,只将它们视为属性和函数,以及它们如何相互关联或继承。例如,当您看到一个人时,他们是一个对象,因此将代表一个类。它们具有头发颜色,肤色,身高等属性。它们也具有某些功能。他们走路,说话,睡觉等。这些人执行的某些功能会返回结果。例如,他们的工作函数返回美元金额。您可以对看到的所有内容执行此操作,因为所有内容都是对象。自行车,汽车,星星等

  2. 在对项目进行编码之前,请使用便利贴和干擦板设计它。这将是一个很好的实践,直到您掌握了这一点。考虑一下您的特定对象/功能/属性。这些项目中的每一个都有其自己的便笺。将它们作为层次结构放在干擦板上。在这方面,功能/属性将放置在对象下方。如果有另一个对象,请对该对象执行相同的操作。然后问自己,这些贴子注释(对象/功能/属性)是否相互关联。如果两个对象使用相同的功能,则创建一个父对象(便利贴),并将其置于其他对象的上方,并在新注释下使用可重用的功能。使用干擦标记从两个子对象到父对象画一条线。

  3. 完成所有这些操作后,请担心类的工作原理。


15

我的建议是学习一些不同的东西。

学习函数式编程,并将从中学到的知识应用到OOP。如果您了解C ++,请进行通用编程。

学习非面向对象的语言。

不仅因为您应该同时使用所有这些东西(您应该),或者因为它们应该完全替代OOP(它们可能不应该),还因为您也可以将其中的经验教训应用到OOP中。

OOP的秘密是使用它并不总是有意义。并非所有的东西都是一堂课。并非每个关系或行为都应建模为一个类。

盲目尝试应用OOP或努力编写最佳的OOP代码可能会导致大量过度设计的混乱,导致抽象和间接级别过多,灵活性极低。

不要尝试编写好的OOP代码。尝试编写好的代码。并在实现目标时使用OOP。


实际上,原始的Kay的OOP很好地完成了构建反应式系统的唯一任务,而现代OOP实施却失败了。甚至是他们唯一的任务!
rostamn739

12

在许多领域,都有一个“尤里卡”时刻,所有事物都融合在一起。

我记得在高中时感到沮丧。我不知道在证明的每个步骤中应用哪个定理。但是我一直坚持下去。我详细学习了每个定理,并研究了它们如何在不同的示例证明中应用。我不仅了解每个定理的定义,而且了解如何使用它,因此我建立了一个熟悉的技术的“工具箱”,可以根据需要进行提取。

我认为编程是一样的。这就是为什么要研究和分析算法,数据结构和设计模式的原因。读一本书并获得技术的抽象定义是不够的。您也必须在行动中看到它。

因此,除了练习自己编写代码以外,请尝试阅读更多代码。那是开源的美,您可以下载大量代码进行研究。并不是所有的代码都是好代码,但是学习坏代码可以像学习好代码一样具有教育意义。


同意尤里卡的时刻。我曾经对Supertux的模式和建筑有同样的感觉,有一天,我的思想才刚刚开放。我不得不读很多东西。
GR7

10

学习另一种语言!大多数仅使用Java的开发人员(仅作为示例)对OO的了解有限,因为他们无法区分语言功能和概念。如果您还不了解它,请查看python。如果您了解python,请学习Ruby。或选择一种功能语言。


7

询问您的问题;)

练习,练习,练习。

查看您自己的代码,并从错误中学习。


1
按照尼尔在这里的回答,您的代码及其代码有何不同?您可以<del>偷</ del>借用他们的模式吗?:-)
Frank V


4

您编写的代码越多,您就越会注意到某些编程实践的陷阱。经过足够的时间和足够的代码,您将能够识别这些陷阱的警告信号并能够避免它们。有时,当我编写代码时,我会想起这个痒,告诉我,即使它可以满足我的要求,也可能有更好的方法。我最大的编程弱点之一是“过度分析”事物,以至于开始显着减慢开发时间。我试图通过在设计上花更多的时间来防止这些“麻烦”,通常这会减少编写代码的时间。

...我秘密地看着同事们羡慕的一些事情。他们中的许多人似乎都有一些我不具备的内在面向对象的本能-无论我如何努力...

我想您已经在这里回答了自己的问题。阅读好的代码是一个好的开始,理解好的代码甚至更好,但是理解获得好的代码的步骤是最好的。当您看到令人羡慕的某些代码时,也许您可​​以问作者,他/她是如何得出该解决方案的。这完全取决于您的工作环境以及与同事的关系。无论如何,如果有人问我我编写的任何代码背后的思考过程,我会毫不犹豫地告诉他们,因为我知道我希望他们为我做同样的事情。


4

语言设计人员以不同的方式解释了“面向对象程序设计”。例如,看看最初使用术语OOP的人Alan Kay是如何定义的:

对我而言,OOP意味着仅消息传递,本地保留和保护以及状态过程的隐藏以及所有事物的极端后期绑定。可以在Smalltalk和LISP中完成。可能还有其他系统可以做到这一点,但我不知道它们。

(引自http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en)。

他不考虑Java和C ++ OOP语言似乎很奇怪!但是,作为第一种也是最好的OOP语言(Smalltalk)的设计师,他有自己的正当理由。为什么艾伦·凯(Alan Kay)认为Lisp是一种面向对象的语言,而不是Java?这个问题要求声称了解OOP的任何人认真考虑。

Erlang具有完全不同的OOP含义Scheme具有另一种含义。值得考虑所有这些替代观点。如果可能,请学习所有这些语言!这将使您拥有更广阔的视野,将一些强大的新工具掌握在手中,并使您成为更好的程序员。

我总结我的实验与实施的OOP语言的基础上,从Smalltalk的,计划和Erlang借来的想法在这篇文章中


4
       public void MasteryOfOOP() 
    { 
       while(true)

        /* My suggestion is: */
     DO: find a lot of well-written object oriented code and read it.  Then 
try to use the insights from it on your own coding.  Then do it again.  Then 
have a colleague who is a good OOP look at it and comment. Maybe post a chunk 
of your code on SO and ask for how it could be improved.

        Then read some more of those books.  Maybe they make a little more 
sense now...?

        Now go back to the top of this post, and do it again. 

        Repeat Forever.

        }
    }

3

如果您不知道如何设计面向对象的系统,请从数据开始。找出需要跟踪的内容以及自然而然的信息(例如,将汽车模型的所有规格很好地结合在一起)。

您决定要跟踪的每种事物都将成为一个类。

然后,当您需要执行特定操作(例如,将汽车模型标记为退役)或提出特定问题(例如,询问在给定年份内售出多少给定汽车模型)时,就可以加载该功能在与之交互最紧密的类上。

通常,对于给定的代码,在类结构中应该总是有一个自然的地方。如果没有,则表明存在需要建造结构的地方。


3

有关对象的信息太多。最重要的是掌握基础知识,一切都更容易就位。

这是一种思考对象的方法。考虑一下过程语言中的数据结构。他们是一群没有行为的领域。考虑一下接收指向这些数据结构的指针并对其进行操作的函数。现在,不要将它们分开,而是在结构的定义内定义函数,并假定函数通常会收到指向要操作的数据结构的指针。该指针称为此。总之,将对象视为状态(数据)和行为(方法-OOP中函数的奇特名称)的组合。

这是绝对的基础。您必须绝对掌握另外三个概念:

继承-这与代码重用有关。

封装-这就是从接口隐藏实现的全部内容。简而言之,除非另有说明,否则所有内容都应该是私有的。

多态-引用变量的类型无关紧要,但是实际实例的类型可以知道调用哪种行为(方法)。Java很难使这个概念非常明显,因为根据定义,一切都是多态的。.Net使您在决定什么是多态和什么不是多态时更容易理解,从而注意到行为上的差异。这是通过虚拟和替代的结合来实现的。

如果对这些概念有很好的理解,那么您会很好的。

最后一个提示:您提到最好的书。您是否读过Bruce Eckel的“ Java思维”?我对那些开始使用.Net的人也推荐这本书,因为OOP概念已经明确列出。



2

OOP技能会随着时间而增长。阅读1、2 ... 10本书不会减少阅读量。练习编写一些代码。如果您在编程环境中工作,那可能会有所帮助。如果没有尝试进入。提供免费开发某些应用程序的机会。你必须弄脏你的手。请记住...没有任何应用程序从一开始就是完美的,这就是为什么要进行重构的原因。

另外...不要对OOP过于迷恋...随着时间的流逝,有些事情会发生。担心开发功能齐全的应用程序。


2

尝试使用Self编程,Self是最纯正的OO语言之一。实际上,它是如此纯净,以至于它甚至没有类,只有对象。它也没有变量,字段,静态变量,属性,只有方法。同样有趣的是,系统中的每个对象也是屏幕上的对象,反之亦然。

关于Self的一些有趣的论文是使用SELF 4.0的基于原型的应用程序构建(Self教程),Self:简单性的力量无类组织程序。另外,《自我:视频》(Randall B. Smith; Dave Ungar)也很棒,有两位语言的设计师解释了Self的想法。

实际上,这几乎对任何概念都有效,至少对我而言:找到最能体现您想要学习的概念的语言,然后使用它。


2

在我尝试编写类似于银行的程序来处理交易,计算利息并跟踪所有内容之后,OO终于为我点击了。我在学习Java时就做到了。我建议您尝试一下,完成它,然后在完成后,查看良好的解决方案,看看可以做得更好。


2

我也认为OOP技能主要是通过练习来增强的。如果您已经在公司呆了三年多,可以考虑更换公司。当然,这并非对所有工作都有效,但通常一个人会习惯于公司的项目和实践,并随着时间的流逝而停止前进。


1

卷起袖子并编码!


4
您认为他在做什么?他正在寻找另一种方法。
2009年

鲁德维:他已经接触了足够多的方法。他需要使用它们。
约翰,2009年

2
我讨厌这些答案。实践使人永久而不是完美。
马丁,

每当我看到有人说他读了很多书(他有)却仍然听不懂时,他们就没有足够的尝试。如果您不喜欢我的答案,IDGARA,但是尝试工作是我取得最大进步的地方,没有找到其他让我感到困惑的意见。
约翰,2009年

1

您自己说了答案:练习。最好的解决方案是开发游戏。使用您在那本书中学到的概念。


1

您是否已经阅读了第一版Scott Meyers的“ Effective C ++”一书中有关面向对象的一章?它没有在以后的版本中使用,但这是一个很好的解释。标题基本上是关于适当约定的“说出您的意思,说出您的意思”。

实际上,您可能希望在这里看到我对类似问题的回答

高温超导

干杯,


0

规划事情。问自己,您希望对象如何彼此关联,并找出如何进行更改和模块化。

编写代码的方式是,如果您想更改1条代码,则只需更改1条代码,而不需要更改其50个实例。


0

不能通过阅读数千本书来掌握OOP。相反,您必须感受内在的概念。读任何东西,但要尝试去阅读。在您的脑海中建立一个概念,并在遇到新情况时尝试匹配这些概念。探索新事物时,验证并更新您的概念。

祝好运!


0

啤酒有帮助。认真地。躺在沙发上,躺着A3大小的便签本,钢笔和啤酒。将狗,猫和妻子锁在外面。放松思考一下问题。甚至不敢在上面绘制API!

流程图,责任卡(CRC)和啤酒(但不要太多)有很长的路要走。

重构代码最简单的方法就是不必首先进行重构。


-1

http://misko.hevery.com/code-reviewers-guide/

这些简单的小规则将使您成为一个更好的OO程序员。在编写代码时,请认真遵守规则,您会发现自己的代码比以前更好。

您还将需要学习“扎实的原则”:http : //butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

尽管这些原理和编程方法引起了争论,但它们是真正编写出色代码的唯一方法。

您可能已经以这种方式编写了代码,却一无所知-如果是这样,那太好了。但是,如果您需要努力奋斗的目标,那么这就是黄金标准。


猜猜为什么YouTube现在看起来如此糟糕?因为Google搞砸了,您知道这种直觉在哪里工作?在Google中。他们搞砸了一切。但是给出一个原因:这个家伙只关心“可测试性”。可编程性是与此不同的概念。可测试性使程序变得更糟,因为它们需要破坏封装,尤其是i OOP。
luke1985

-1

放弃!为什么需要那个OOP?只需编写一些可用的应用程序即可。不使用OOP,程序或功能方法。

您选择Python语言的Whataver方法应该易于实践。


+1为第一段。-1秒
nawfal 2012年

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.