用于理解C#中OO设计的A-Ha时刻

时间:2009-01-24 17:11:45

标签: c# oop

我已经学习了C#几年,贪婪地阅读,甚至从微软那里学习了一些C#数据访问课程。我也一直在读OOP上的书。我正在编写一个基于Web的数据库应用程序。虽然我的职位不是“程序员”,但我很幸运能够将其作为一个辅助项目。我在80年代早期用Basic进行编码,甚至擅长利用pokes和peeks来操纵Apple []和TRS-80让我的朋友惊叹不已。但这是一种非常线性的编码方法。

所有这一切都说,有些东西不是跟我点击。我没有C#或OOP的那个时刻让我能够坐下来,打开VS2008并开始编码。我必须研究其他人的代码,以至于我似乎没有自己做任何事情。我气馁了。

这不像我没有能力。我很快就拿起了t-sql。有人可以告诉我他们想从数据库中获取什么信息,我可以在几分钟内编写出tsql来给他们想要的东西。 SQL是我得到的东西。 OOP或C#不会发生这种情况。当然,C#本质上更复杂,但在某些时候它必须点击。正确?

我读过stackoverflow,我对你们这些人的无限智慧感到不知所措。

点击它对你有什么影响?

编辑添加: 这里的很多答案都非常出色。然而,特别是一个人似乎已经上升到顶部,那就是我标记为“答案”的那个。我也不愿意用答案标记我的问题。

30 个答案:

答案 0 :(得分:28)

了解接口是为我做的。来自脚本背景并切换到OO,我没有看到如何创建所有这些类更有效。然后我读了Head First Design Patterns,突然间我看到了原因。这不是最详细的书,但它是解释OO编程的“原因”的第一步,这是我极其挣扎的事情。

希望这有帮助。

答案 1 :(得分:26)

SO上的大多数海报都不是特别聪明。有几件事可能会让你认为是这种情况。首先,只有碰巧知道或认为他们知道答案的人才会愿意回应。其次,不正确/错误的问题和答案是不可见的。第三,集体知识自然比个人知识大得多。

你误认为智力的东西,是在竞技场度过的时间。你将花费更多的时间和精力来学习更好,更有知识的人。从你的意思来说,你并没有以最佳方式接近事物。理解特定语言只提供语法和语法规则。成为优秀开发人员的关键是成为一名优秀的思想家。不要专注或挂断语言。

Craig Larman和Bruce Eckols以及Head Start书籍非常适合这种学习模式。但是,我必须警告你,阅读书籍和做练习是不够的。你必须让自己沉浸在与其他开发人员的讨论和反馈中(当然,除非你是一个非常聪明的人 - 在这种情况下你只需要得到它......)。

你已经证明了比智力更重要的特质。你有谦虚。如果你有谦卑和坚持,你将比SO上的绝大多数海报更有效,更有见识。

谦卑也很重要,因为它可以帮助你应对这样一个事实,即无论你多努力工作和学习多少,你都不会比Jon Skeet知道更多。

答案 2 :(得分:13)

编写代码。很多。糟糕的代码,良好的代码,无用的代码 - 没关系。写吧。当你厌倦了编写代码时(如果你偶尔没有厌倦它,那么你的写作就不够了)阅读博客,杂志和有关代码的书籍。

然后,回过头来看看你之前编写的一些代码。重构它,清理它并改变设计。添加功能,修复错误,无论什么 - 无所谓。删除现有代码,并编写更多代码。

在某些时候,你会开始在C#中思考 - 就像在SQL中一样。

请注意,这类似于通过沉浸其中来学习外语。当然,你可以在学校学习,读书,听录音带。但是,没有比学习外语更好的方法了,而不是每天都在学习外语。

答案 3 :(得分:4)

第一个问题:你每周编码多少小时?

第二个问题:你在现实生活中知道谁得到了它?和他们谈谈!!!

...

面向对象编程是一种编程方式,可以组织并最大限度地减少重复自己。这样可以减少代码,更容易更改代码(因为所有内容都只在一个地方)。

你遇到了问题,所以我可以假设你并不需要继承。继承是减少重复代码的一种方法。 OOP的另一个主要部分是类。类的重点是将事物分组,使它们保持良好的组织,并将它们封装起来以减少耦合(从而使代码更容易变更!)

这几乎就是它。

现在出去全天候编程,找到现实生活中真正理解这些东西的人,然后说出他们的耳朵。

祝你好运。

答案 4 :(得分:3)

我不确定你在C#旅程中的位置,但我当然发现Head First C#非常好读,并将其中的迷你项目用作练习。作为一个在业余时间学习C#的人,在阅读本书之前大约一年半的时间里,它给了我一些迷你的“Aha”时刻,例如代表和回调。

当然,其中的一些例子是人为设计的,就像许多其他编程书籍一样,但嘿,谁不想建立自己的太空入侵者?!

答案 5 :(得分:3)

我认为对我而言,当我停止在汽车和蓝图方面考虑OOP时,以及我的老师试图闯入我的大脑的其他隐喻,并开始考虑它的问题。在实际代码中的实际应用。

我写的第一个对象是得到它,是一个创建数据库连接的小类,并封装了一堆用于执行SQL查询的方法。在那之后,OOP从老师谈到的东西变成了对我和我的代码实际上有用的东西。

所以,我的建议是,继续学习,最重要的是,尽可能多地编写代码。什么使点击给我或其他人点击,可能不会让你点击,所以你需要打造自己的道路。

正如其他人建议的那样,可能会暂时放弃C#,尝试使用其他语言。拓宽视野,学习一些C ++,或者使用Python或Ruby。你会以新的视角和清晰的调色板回到C#,作为一个更好的程序员,也许事情会变得更加可点击。

答案 6 :(得分:3)

我的“点击”并没有直接发生在与C#的关系中,但我认为有三个实例与我在C#中轻松工作的能力有关。

1)我8岁,试图编写一个看似简单的装配例程来清除Commodore 64上的图形屏幕。在我用Basic编写循环的那一刻,我碰到了一堵墙。据我所知,没有办法用汇编语言编写一个可以跨越256(单字节)屏障的循环。我查阅了我所拥有的书籍,却找不到解决办法。 (答案肯定不是为每组256行像素写一个3字节“代码行”。)几天后,它只是打击了我。 (解决方案是编写两个循环,外部循环实际上改变了内循环的代码。)这不是我们当前语言需要做的事情,但我几乎可以感觉到我的大脑在增长。

2)这件事发生在我很小的时候。 (也许是10?)我的钢琴课程已经发展到我不得不每只手演奏不同节奏的歌曲。几个星期以来,我一直在挣扎这首歌(部分是因为我倾向于避免必要的练习)。实践有所帮助,但还不够。然后,有一天,我坐下来突然点击。在此之后,这首歌几乎很容易播放。

3)在大学期间,在我为数年乐趣编程之后,我的导师为我们提供了入门级的OOP任务。我们使用了一个包含其他几个对象的对象。每个人都在屏幕上画画。要完成任务,所需的一切都需要旋转45度。几乎所有学生(包括我自己)都得到了部分功劳,因为我们在包含对象内旋转了每个对象。获得全额信贷的人只需旋转一件事:包含对象。我没有听到“点击”,但这一课确实帮助我理解了OOP。

要打破自己的障碍,您可以按照上述建议。也许找到一个你清楚理解的简单项目,并在C#中实现它。或者你可以把你理解得很清楚的物理对象(比如带方向盘,车轮,引擎,制动器等的汽车),并用C#中的类进行建模。当然,您也可以通过简单地选择一个您没有得到的功能或关键词来实现“点击”,并在点击之前对其进行研究。只需点击一下即可完全打入C#。

无论哪种方式,玩得开心! (有趣的事情总是更容易让你的潜意识分析,而你没有专注于它。)

答案 7 :(得分:3)

我同意Jeremy McCollum的观点。也许你需要停止阅读开始做

好的,不要停止阅读,但在某些时候,成为更好的程序员的唯一方法就是实际使用你想要学习的工具/语言。

我的情景很像你的情景。虽然我的日常工作 程序员,但它不是C#甚至是.Net。我得到硬币的方式是实际开始研究一个真正的项目。它甚至不是一个大项目,但它是一个真正的项目,我必须学习如何做一些我从未做过的事情(在C#中)。

完全按照你说的做不到:坐下来,打开VS2008,然后开始编码。做吧!

将其视为真正的工作,不容易出局!假装你的工作取决于它。对我而言,实际上确实如此,因为我希望将来某个时候能够获得一份C#工作。如果我无法完成项目,那将永远不会发生。

答案 8 :(得分:3)

试试这个:find a big switch statement and refactor it into classes。这是一个很大的'啊哈!'对我而言。这是一个经典的重构,说明了程序设计和OO设计之间的区别,并且不难执行。然后意识到if语句是小开关。

现在,去阅读design patterns。用它们写一些类。

接下来,获取一些提供某些功能的类,并将其重写为without return statements,最好使用接口。这是另一个大'啊哈!'为了我。

事实上,一个好的选择是花一个星期阅读c2.com

希望帮助您完成旅程。

答案 9 :(得分:3)

  1. 对我来说是第一步:了解Turbo Pascal中的FOR循环。这永远改变了我的生活。
  2. 第二步:理解每个对象都像一个按钮(或任何其他ui控件),通常是不可见的。
  3. 您可能有兴趣阅读此内容:

    Coding Horror: Separating Programming Sheep from Non-Programming Goats

答案 10 :(得分:3)

我没有给你真正的建议,因为你是完全正确的:它点击。 OOP很难解释,所以每个人都能得到它,就像人们很难理解Windows消息,外国主键以及其他值得一提的话题一样。

我建议您尝试自己做一个真实的项目。它不一定非常复杂,但它必须包含几个类,所以你可以用继承和其他甜蜜的OOP来弄脏你。

我不认为任何数量的阅读都可以取代你自己的经历......直到它点击只是假装你在黑暗中独自玩耍或其他......

答案 11 :(得分:3)

我记得这种感觉。我被签约在ASP.NET和C#中使用应用程序。问题是,我不是C#开发人员,雇主知道它!但是因为我之前有过编程经验,所以他们鼓励我试一试。我是一名PHP开发人员,踏入.NET世界。

第一周令人沮丧。我记得生气,问为什么我不能只包括(“sideNavigation.php”)来获取页面上的导航。相反,我必须做一些控制,将其添加到其他控件 - 它没有任何意义。但我一直在读。

ASP.NET开始流行起来,而且标记很有意义。当我学习了标记方面时,我开始变得更熟悉代码隐藏。我知道更多的东西存在哪些属性和方法,以及它们接受了什么类型的值。

当然像www.learnvisualstudio.net这样的地方也派上用场了,还有关于C#和VB.NET的视频教程。

今天我仍然是一名PHP开发人员,但我对.NET感到非常满意,我可以回到VS2008并修补一下,直到我得到我的解决方案。

随着时间的推移,我的朋友。另一个有用的事情是找到一个.NET用户组并定期访问

答案 12 :(得分:2)

This inflammatory article on why getters and setters are evil挑战了我以为我在做OOP的方式。文章中提出的一些观点可能很简单,但“尽可能地告诉,不要问”的想法彻底改变了我对OO设计和编写代码的看法。

答案 13 :(得分:2)

您面临的挑战可能是您对SQL过于熟悉。 OO和Relational是两个相互矛盾的概念。使用关系工具,您主要关注数据及其表示方式。每个编程任务都涉及以完成所需任务的方式处理数据。

另一方面,OO涉及行为。 OO系统中的编程任务涉及在适当的实例中调用行为以完成任务,并设计将以预期方式运行的对象类。

答案 14 :(得分:2)

了解C#中的Generics是什么给我做的。现在我永远在if-else语句中思考。

答案 15 :(得分:2)

如前所述,请查看设计模式。

另外,我发现叔叔鲍勃的东西对学生和导师很有用,特别是一些oo设计原则:http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

答案 16 :(得分:2)

嗯,这就是我看到你问题的方式。事实上,你来自SQL,一种4GL(第四代语言),它更接近人类语言,而不是像C#这样的3GL,就像有人用来驾驶飞机一样,没有什么比驾驶汽车更重要。您应该尝试学习如何骑自行车(2GL类似汇编语言)或尝试驾驶低端汽车(如Fortan或C)来欣赏C#等语言。

答案 17 :(得分:2)

  1. 你需要一些你需要/想要完成的东西。
  2. 坐下来创造它。
  3. 在创建它时,你必须弄清楚你不知道的事情。这可能是识别这些东西的最佳方式。
  4. 当你完成并有一些工作时,你会回顾它并思考你可以采取哪些不同的方式来更好地组织它。
  5. 对这些特定的事情和可能的方法进行一些研究。
  6. 创建其他内容并反思。
  7. 重复直到你有一个哈哈时刻。
  8. 对我而言,我的第一个时刻是在第三周的培训期间教授霍尼韦尔汇编程序,并最终了解计算机是如何工作的。

    我的OOP a-ha时刻是在实时中继梯形逻辑课程中,我决定创建一个库来模拟我们必须编写程序的Texas Instrument硬件。它允许我为课程编写/测试我的程序,而无需去学校并使用真正的硬件。我睁开眼睛看着OOP。我相信a-ha时刻的发生是因为我能够(使用代码)模拟真实的东西。

答案 18 :(得分:2)

关闭主题,你知道你在哪里得到那个短语,“a-ha时刻”:它是来自一本书,来自别人,还是原创的?因为我想我记得有人在使用同一个短语,当我在1994年约在线学习OOP和C ++时。

无论如何:你的问题。

和你的一样,我的编程经验早于OOP:我也做了一些基本的编程,而且,C。

在某种程度上,正如你所说,“一种非常线性的编码方法”。

当我开始学习C ++时,我在C语言中专业地编程。因此,在能够“坐下来,打开VS2008,并开始编码”方面,我每天都在做这件事:我坐下来编写,在C中。

这是事件驱动的编程:软件对事件作出反应,输入:来自网络,来自各种设备,来自UI ......所以这样,即使这个C代码根本不是线性的作为我们用来写的必要的基本代码(“读取按键,写入屏幕”)。

这是一回事:事件驱动的编程。事件驱动的编程不是线性的,它可能有点难以概念化:一堆事件处理程序,一些独立的,一些在非固定序列中与每个交互。事件驱动的编程不是OOP(你可以用C编写事件驱动的程序),但OOP众所周知的事情之一是GUI和事件驱动的编程。我建议OOP并不一定能让它变得简单:问题本来就很困难,而OOP让它更容易,也不容易。

所以这是另一回事:如果你可以做到,那么你就做对了。不要指望一切都会变得容易。一个好的解决方案可能会使解决方案变得简单明了,但是为大型难点问题开发一个好的解决方案并不容易,我们可能会感谢OOP让它成为可能。

无论如何,回到我的故事:我在C编码。我逐步学习使用C ++,例如:

  • 我有一堆数据(结构),以及对这些数据进行操作的一系列函数......将函数放在与它们操作的数据相同的结构中,“函数”变成“方法”< / LI>
  • 现在数据已经关联了应该对该数据起作用的方法,使数据变得私有,以便其他方法无法直接触及它...封装和/或信息隐藏
  • 现在我已经有了明确定义的类(其中一些已经作为数据成员彼此包含),开始使用继承来实现不同类型之间的相似性和相异性

对我来说,其中一个“a-ha”时刻是我们为不同类型的传真设备驱动驱动程序,每个传真设备都有不同的低级API。使用OOP我们可以写...

  • 一个简单的抽象类,它声明了我们希望所有设备都支持的简单的高级API(如,sendFaxreceiveFaxcancel等)< / LI>
  • 子类,它使用特定硬件的API来实现从抽象基类继承的抽象API。

我刚想起别的东西。当我学习C ++时,我阅读了各种书籍:

  • 用C ++思考学习阅读C ++的语法
  • 有效的C ++ 学习编写C ++时要避免的各种规范性战术错误

阅读完这些内容后,经过大约6个月的练习,我可以使用C ++作为更好的C语言。

我读过的下一本书之一是四人帮的设计模式:读这本书对我来说是一个“a-ha”时刻,它让我想到,“如果那些其他书籍向我展示了如何用面向对象编程语言编写,本书向我展示了为什么我想要的。“

所以,有一个建议:阅读设计模式

我一直在谈论C ++等等,因为那是我第一次拥有C ++的时代。我认为这是相关的......好好理解OOP和C ++,我花了不到一个星期的时间来“坐下来,打开VS2008,然后在C#中开始编码”。

答案 19 :(得分:2)

我完全同情。我有英语和电影学位;我在二十几岁之前完成的唯一编程是在申请时[e,当我12岁时。经典ASP是我第一次涉足网络编程,我只学习,因为我必须,作为一名技术作家在内联网项目记录房地产软件。

但最终编程开始了,我决定开始学习如何做正确的事情。过渡并不容易。但是我可以说学习C#用于Web开发,特别是如果你还没有“grok”OO,那可能是令人生畏的 - 主要是因为OO非常关注创建和管理状态和状态,而Web本质上是无状态的。

信不信由你,我学到了更多关于OO用ActionScript编写带有JavaScript和Flex应用程序的Ajax应用程序 - 比如构建有状态客户端 - 比我试图强迫C#进入我的大脑,因为Ajax应用程序和Flex应用程序强迫你以国家的方式思考问题。在花了几年时间(是的,几年)之后回到C#编写了大量的JavaScript代码,以及大量的Flex代码,并且阅读了大量的两者,实际上非常简单,因为到那时,我意识到了C#应该可以作为OO语言使用。

Head First系列书籍也很棒 - 人们在这里轻描淡写,因为他们相当愚蠢,但是他们教授了很多概念,我很惊讶他们的课程对我的影响有多大这些年。 Try the OO title。并花一些时间来使用JavaScript。也许看看Douglas Crockford's工作。它会点击。请给它一些时间。

答案 20 :(得分:2)

Dunno ......对我而言,Turbo Pascal 6引入了OOP的概念,但当时我并没有完全理解它。然后我学会了C ++,一切都立即变得清晰。来自C ++,C#看起来非常简单,所以我不能说我在C#或.NET上有过这样的时刻。

我想你只需要编写代码。很多代码。

答案 21 :(得分:1)

以下没有为我点击OO(当我听到它时它已经有了),但我确实发现它是一个非常好的简洁描述。

我的一位同事喜欢引用他的一位大学教授的陈述,其中有类似的话:

  

写出一个网格,其中包含由数据类型标记的行和由数据上的操作标记的列。如果您横向切片实现,那么您正在进行面向对象的编程。如果你将它垂直切片,那么你就是在进行函数式编程。

尝试将OO视为一种组织代码的方法,在该代码中,程序员定义的数据类型的操作的实现被捆绑到数据的定义中。

答案 22 :(得分:1)

面向对象的设计一般需要精神上的依偎,但对我来说,大学使用JAVA教我们OOD后C型OOD似乎很自然。

经过大量的爱好项目实践,需要优雅的架构来满足一些用例--OOP似乎变得越来越自动化。

答案 23 :(得分:1)

这里有很多好的建议,但只有桑普森先生暗示找到合适的人回答问题会有所帮助。我无法计算有多少次我一直在看某人的工作,打断他们问一个问题,“你为什么要做 X ?”不久之后又有一个哈哈时刻。并非总是如此,但要求足够多的人提出足够多的问题,心灵融合就会发生,并且它会很好。

答案 24 :(得分:1)

我认为真正理解任何新技术的唯一方法就是日复一日地使用它。当然,你可以在很高的层次上学到很多新东西而不会太深入,但为了得到那个“啊哈”的时刻,要真正理解语言和模式,你必须投入大量时间进行做它

可悲的是,这意味着你的主要工作必须是用C#编程。如果您只是在这里和那里进行一系列的辅助项目,那将是令人沮丧和缓慢的。

根据我自己的经验,我的意见......

答案 25 :(得分:1)

关于OOP的“a-ha”时刻来自于使用.NET框架。起初,我很懊恼将文本写入文件是多么笨拙。然后我意识到我不需要决定我的对象是否要打印到文件;我可以让它使用TextWriter,并让任何创建它决定输出将转到文件或控制台的位置。然后我意识到创建TextWriter的子类将输出发送到TextBox是多么容易。然后我意识到这种思维是框架的所有设计的基础。

突然(这是非常突然的,就像它在一个周末发生的那样)这个框架以一种绝对没有的方式有意义。而且我也意识到使用框架设计者在设计我自己的程序时使用的原理很容易。

答案 26 :(得分:1)

嗯,工厂和单身人士模式为我做了。我仍然遇到麻烦,我觉得我没有使用完整的OO功能,但它始终是一个学习曲线。

我遇到麻烦的事情是弄清楚哪个班级应该做什么,例如如果一个员工对象有一个RaiseSalary方法,该方法需要一个金额,或者PayMaster对象应该有一个方法来获取员工列表并计算提高他们的工资量?我知道的一个例子,但它就是一个例子:P

答案 27 :(得分:1)

任何语言的第一步应该是“Hello World”教程。这种学习方法背后的神奇之处,也就是所谓的边做边学,是一种直接需要作为主要学习动力的事实。  我本人就是一名C#.NET开发人员,目前我正在努力学习F#。编写HelloWorldApp之后我应该采取的步骤设置为小而简单的目标,如

编写一个控制台应用程序,在网上下载一些页面并显示其HTML内容 再做一次,但现在是异步的 再做一次,但现在并行多页。

这就是我学到的东西。对于OOP来说,事情变得更复杂,你也应该阅读其他人的代码和文章。有助于您自己学习OOP和重构的一件事就是重用自己的代码。在上面的例子中,你会注意到为同步下载页面编写的代码非常类似于异步执行的代码,它们甚至有一些100%相等的行。你应该做些什么来学习OOP是重构并封装你的代码,所以你可以选择你想要的(同步或异步)下载类型,同时为两个选项编写的代码中的重复次数最少。如果使用TDD(测试驱动开发),学习曲线将会改善。

答案 28 :(得分:0)

接口。我在第一次使用时理解了OOP和继承的基础知识,但接口花了不合理的时间让我掌握。

我第一次听说这些事情时,我立刻对自己说:“为什么我曾经需要创建一个伪类_我的接口的宠物名称}任何实现?这不是整个继承点,所以我不必一遍又一遍地重新输入相同的实现逻辑吗?“

所以,有一天,我对自己说,“我想知道你如何编写各种类型的方法,这些方法具有特定的方法,而不必牺牲类型安全性”。然后它发生在我身上:这正是接口的用途!一旦我理解了,一切都有意义,而且我自己发明了一些与工厂和观察者模式非常相似的设计模式。

当它与我点击时,我能够在完全不同的层面上考虑OOP。

答案 29 :(得分:0)

让我点击OO的东西就是在IoSelf中学习基于Prototype的OO。 C#的OO是一个非常不同的野兽:不优雅和简单,但毛茸茸和复杂。简单并不代表不那么强大,相反!我建议先学习一个简单而优雅的系统。然后,如果你眯眼,你可以在C#中看到OO。

另一个A-Ha时刻是理解类型系统如何防止在编译时对错误的对象调用错误的方法。由于强制转换,C#的类型系统在所有情况下都不会这样做。从对象技术杂志上阅读articles type theory时,我得到了这个A-Ha时刻。