如何向程序编程人员讲授面向对象的编程?

时间:2009-07-15 03:21:50

标签: oop

我被要求开始向一组程序程序员教授C#和OO概念。我已经searched for ideas了解了从哪里开始,但除了最初要避免的主题外,我还在寻找与主题相关的一般共识。

修改

我打算每周分30分钟提供信息,直到不再有意义见面。这些演讲针对的是从新手到专家等各种技能水平的同事。

19 个答案:

答案 0 :(得分:24)

您可以做的最好的事情是: 一吨的Q& A

维基百科的procedural programming(PP)文章确实应该在你应该开始的地方点击:

  

程序编程使用   操作数据的程序   结构,面向对象   编程将两者捆绑在一起   所以“对象”在其“自己的”上运作   数据结构。

一旦理解了这一点,我认为很多都会落实到位。

一般

OOP是需要时间“获取”的事情之一,每个人都有自己的路径去实现目标。在C#中写作时,并不像代码尖叫,“我正在使用OO原则!”在每一行。它更像是一个微妙的东西,比如foreach循环或string连接。

设计中心

制作之前,始终使用某些内容(重复)。

首先,使用一个对象,并展示与PP的基本差异。像:

static void Main(string[] args)
{
    List<int> myList = new List<int>();

    myList.Add(1);
    myList.Add(7);
    myList.Add(5);

    myList.Sort();

    for (int i = 0; i < myList.Count; i++)
    {
        Console.WriteLine(myList[i]);
    }
}

首先使用对象(以及其他OO东西) - 在被迫创建自己的东西之前 - 引导人们沿着这条路走下去,“好吧,我正在制作像我刚刚使用的东西,“而不是”WTF我打字?“

继承(这是一个陷阱!)

我不会花很多时间继承遗产。我认为,对于这方面的重大教训来说,这是一个常见的陷阱(通常会像其他人指出的那样制造陈词滥调的动物等级)。我认为了解继承,了解如何使用 .NET Framework是至关重要的,但它的细微差别并不是那么重要。

当我使用.NET时,当我使用 .NET Framework时,我更有可能“遇到继承”(即“此控件是否有{{1} }属性?“或”我只是调用它的Content方法。“而不是在我创建自己的类时。非常(非常(非常))很少我觉得需要制作一些模仿动物王国分类结构的东西。

<强>接口

编码到界面是关键的中级概念。它在任何地方都使用,OOP使它更容易。这方面的例子是无限的。基于我上面的示例,可以演示ToString()接口:

IComparer<int>

然后,通过public int Compare(int x, int y) { return y.CompareTo(x); } 使用它来更改列表的排序顺序。 (当然,在谈到myList.Sort(this)之后。)

最佳做法

由于该小组中有一些经验丰富的开发人员,因此中级课程中的一个策略是展示各种最佳实践在C#中的运作方式。比如,信息隐藏,observer pattern

有大量的Q&amp; A

同样,每个人的学习方式都略有不同。我认为你能做的最好的事情就是有大量的Q&amp; A,并鼓励小组中的其他人进行讨论。人们通常在参与时会学到更多知识,而且你应该更容易接受这种情况。

答案 1 :(得分:12)

如果你强调人们不强调的更基本的概念,那么从程序性到面向对象的飞跃(即使在一种语言中 - 我编写程序性C ++四个月,课程一段时间后感到不舒服)也可以得到缓解。

例如,当我第一次学习OOP时,没有一本书强调每个对象都有自己的数据成员集。我试图编写用于输入验证等的类,而不是理解类是对数据成员进行操作而不是输入。

立即开始使用数据结构。他们使OOP范例看起来很有用。人们会教你如何制作一个“House”课程,但由于大多数初学程序员都想立即做一些有用的事情,这似乎是一种无用的绕道。

立即避免多态性。继承是正常的,但在适当的时候进行教学(而不是仅仅添加到基类)。

当您第一次学习时,操作员重载并不重要,而特殊的ctors(默认,dtor,copy ctor和赋值操作符都有其棘手的方面,您可能希望避免这种情况,直到它们基于基本类设计为止)。

让他们建立一个堆栈或链接列表。不要做遍历棘手的任何事情,比如二叉树。

答案 2 :(得分:7)

分阶段进行。

高级概念:描述对象是什么,并将其与现实生活联系起来。

中级概念:现在他们得到了什么对象,尝试比较和对比。向它们展示为什么全局变量与类中的封装值相比较差。他们可能从封装中获得什么好处。开始介绍OOP的趋势(封装,继承)

低级概念:进一步深入了解多态和抽象。向他们展示如何通过多态和抽象获得更好的设计。

高级概念:SOLID,接口编程,OO设计模式。

答案 3 :(得分:5)

也许你应该考虑一个与工作相关的问题,然后从它的程序实现开始,然后逐步完成(逐个会话)如何实现它的OOP实现。我发现专业人士经常更好地掌握概念,如果它与他们自己工作场所的真实例子直接相关。大多数教科书使用的垃圾例子通常都很难理解,因为它们让学生不知所措,为什么我会想要这样做。给他们一个真实的理由,为什么他们想要这样做,这更有意义。

答案 4 :(得分:3)

教授重构

教授基本知识,最低限度的OO原则,然后动手教授Refactoring

传统方式:抽象&gt;术语云&gt;琐碎的实施&gt;实际使用 (你能看到这里的断开吗?其中一个过渡比其他过渡更难。)

根据我的经验,大多数传统教育在让程序员真正理解OO原则方面做得并不好。相反,他们学习了一些语法,一些术语,他们有一个模糊的理解,以及一些规范的设计实例,作为他们所做的很多事情的模板。这是对OO设计和工程的透彻理解的光年,人们希望有能力的学生获得。结果往往是代码被分解成可能最好被描述为对象库的大块,并且代码名义上附加到对象和类,但是非常非常不是最优的。例如,看到几百行方法是非常普遍的,这根本不是OO。

提供对比以突出重点关注OO的价值

通过预先为他们提供工具来教导学生,通过重构来改进现有代码的OO设计。采用大量的过程代码,使用提取方法多次使用有意义的方法名称,确定共享共性的方法组并将它们移植到自己的类中。用多态替换开关/案例。等等。这样做的好处很多。它为学生提供了阅读和使用现有代码的经验,这是一项关键技能。它可以更全面地了解OO设计的细节和优势。在真空中很难理解特定OO设计模式的优点,但将它与更程序化的风格或笨拙的OO设计进行比较会使这些优点形成鲜明对比。

通过心理模型和表达术语建立知识

重构的语言和术语帮助学生理解OO设计,如何通过代码气味的概念来判断OO设计和实现的质量。它还为学生提供了一个框架,可以与同行讨论OO概念。如果没有汽车变速器的模型和术语,机械师将很难相互沟通并了解汽车。这同样适用于OO设计和软件工程。重构为软件工程的组件和技术提供了丰富的术语和心理模型(设计模式,代码气味和相应的特定重构等)。

建立手工艺的道德

通过教导学生设计不是一成不变的,你可以增强学生对实验,学习和发现能力的信心。通过弄脏手,他们会更有能力解决软件工程问题。这种自信和实用技能将使他们真正拥有自己的工作设计(因为如果他们愿意,他们将始终拥有改变设计的技能和经验)。这种所有权有望帮助培养责任感,自豪感和工艺。

答案 5 :(得分:3)

我会避免“自行车是一种veichle”的方法,并尝试将OO应用于一个相当具体且已经习惯的环境。尝试找到他们都认可的问题域。

练习该领域的基础知识,但试着走向某些“哇!”或者“啊哈!”经验比较早;在Fowlers Refactoring中阅读“替换条件与多态性”时,我有过类似的经历,这些或类似的书籍可能是一个很好的想法来源。如果我没记错的话,Michael Feathers Working effectively with legacy code包含了关于如何将程序性程序转换为OO的章节。

答案 6 :(得分:2)

我是一名vb.net中级程序员,我正在学习OOP。我发现的一件事就是一遍又一遍地讲授这些概念是令人不安的。我认为什么是完美的文档将是从程序编程到完整的OOP的逐步过渡,而不是试图强迫他们理解概念,然后让他们使用所有概念专门编写OOP代码。这样他们就可以修补像“你好世界”这样的小项目而不会受到设计的恐吓。

例如(这适用于VB.NET初学者而不是高级程序程序员)。

我认为第一章应该总是关于一般概念,只有几个例子,但你不应该强迫他们立即严格编码OOP,让他们习惯语言,这对他们来说很自然。当我第一次开始时,我不得不一遍又一遍地阅读手册以记住如何编写代码,但我不得不浏览有关概念的讲座和页面。痛苦! 我只需要记住如何创建一个ReadOnly属性或其他东西。真正方便的是本书的一部分是一个语言参考,所以你可以轻松地在那里查看如何编写代码。

然后,您简要说明表单和所有对象是否已经是对象,具有方法,并显示它们的行为方式以及示例代码。

然后向他们展示如何创建一个类,并让他们创建一个具有属性,方法和新构造的类。然后让他们基本上使用表单或模块中的过程代码从它们切换到为类编写方法。

然后,您可以像使用任何编程语言一样引入更多高级代码。 向他们展示继承是如何工作的,等等。继续扩展,让他们利用他们的创造力来发现可以做的事情。

在他们习惯于编写和使用类之后,然后展示他们如何改进类,在代码中逐一引入概念,修改现有项目并使其更好。一个好主意是在过程代码中采用一个示例项目,并将其转换为OOP中更好的应用程序,向他们展示OOP的所有限制。

现在之后是您进入一些非常先进的OOP概念的高级部分,以便那些熟悉OOP的人已经从本书中获得了一些价值。

答案 7 :(得分:2)

我建议你看一下Head First Design Patterns,它有一些非常好且易于理解的面向对象设计的例子,它们应该会有所帮助。我不会在这一点上过分强调“模式”方面。

答案 8 :(得分:2)

我有点惊讶,有任何纯粹的程序程序员离开; - )

但是,作为80年代早期开始使用COBOL,C和FORTRAN等程序语言编写代码的人,我记得我最难解决的问题是实例化。对象本身的概念并不那么难,因为基本上它们是“带附加方法的结构”(从程序角度看)但是处理如何以及何时实例化一个对象 - 并且在没有垃圾收集的那些日子里 - 销毁它们造成的我有些麻烦。

我认为这是因为在某种意义上程序程序员通常可以指向代码中的任何变量,而不是直接存储该数据项,而只要您实例化一个对象并为其赋值,那么它就是更不直接有形(在C中使用指针和内存分配当然是相似的,如果你的学生有C经验,这也可能是一个有用的起点)。从本质上讲,我认为这意味着你的程序 - &gt; OOPS程序员必须学会在他们的代码中处理另一个抽象级别,并且熟悉这个心理步骤比看起来更困难。因此,通过扩展,我确保您的学生在查看静态方法等可能令人困惑的概念之前,完全可以自行分配和处理对象。

答案 9 :(得分:2)

首先定义一个物体,不是使用一些愚蠢的动物,形状,车辆的例子,而是使用他们已经知道的东西。 C stdio库和FILE结构。它用作具有已定义函数的不透明数据结构。将从程序使用到OO用法的地图映射到封装,多态等等。

答案 10 :(得分:2)

首先,选择像C#或Java这样的语言,并提供大量示例来演示。在深入了解抽象或封装等OO概念的细节之前,始终向他们展示全局或大创意。准备好用充分的现实世界的例子回答很多问题。

答案 11 :(得分:1)

如果他们是优秀的程序程序员并且知道函数的结构和指针是什么,那么工作中最困难的部分已经完成了!

我认为关于面向对象编程如何在过程语言甚至汇编程序中实现的低级讲座可能很酷。然后他们会欣赏编译器为他们所做的工作量;也许他们会找到他们已经知道并且以前使用过的编码模式。

然后,您可以讨论良好的面向对象设计中的最佳实践,并介绍一些UML。

要记住的一件非常重要的事情是,他们不是新生,不要花太多时间在基本的事情上,因为他们会觉得无聊。

答案 12 :(得分:1)

在示例中显示设计模式

那里有一些很好的答案,好吧。我还认为,你应该使用优秀的语言,良好,熟练的例子,但我还有一个建议:

通过研究设计模式,我已经了解了OOP的含义。当然,我之前学过一门OO语言,但在我开始设计模式之前,我并不了解它的全部功能。

我也从罗伯特·C·马丁这样的OO-Gurus学到了很多东西,并且在他的公司网站上发现了非常好的论文。

编辑:我还提倡使用UML(类图)来教授OO / Design-Pattern。

答案 13 :(得分:1)

让它为我点击的是引入重构和单元测试。我的大部分专业编程生涯都是在OO Languages,但我花了大部分时间编写程序代码。你在类X的实例上调用一个函数,它在类Y的实例上调用了一个不同的方法。我没有看到有关接口的重要内容,并认为继承只是一个方便的概念,而且类基本上是一种帮助我们对大量代码进行排序和分类的方法。如果一个人足够自虐,他们可以很容易地完成我的一些旧项目并内联所有内容,直到你进入一个庞大的课程。我仍然非常尴尬地认为我的代码是 bad ,我的架构多么天真。

当我们浏览Martin Fowler的重构书时,它半按了一下,然后在开始编写时完全点击并为我们的代码编写Unit和Fitnesse测试,迫使我们重构。开始推动重构,依赖注入以及将代码分离到不同的MVC模型中。要么它会沉入,要么它们的头会爆炸。

如果某人真的没有得到它,也许他们并没有因为在OO工作而被切断,但我认为我们团队的任何人都没有完全迷失,所以希望你能有同样的运气。

答案 14 :(得分:0)

我发现这本书Concepts, Techniques, and Models of Computer Programming非常有助于理解并给我一个词汇来讨论语言范式的差异。本书并不真正涵盖Java或C#作为00语言,而是涵盖不同范例的概念。如果我在教OO,我会首先展示范式的差异,然后慢慢地看出00语言的差异,他们可以自己学习课程/项目的实际内容。

答案 15 :(得分:0)

成本。解释如何正确使用该语言的功能应该允许以较低的成本编写和维护软件。 (例如Java的Foo.getBar()而不是foo-&gt;栏,这在C / C ++代码中经常出现。)。否则我们为什么要这样做?

答案 16 :(得分:0)

我在高等教育期间学到了OOP。他们在解释概念方面做得相当不错,但在解释原因和时间方面却完全失败了。他们教授OOP的方式是,绝对一切都必须是一个对象,程序编程由于某种原因是邪恶的。他们给我们的例子对我来说似乎有些过分,部分原因是对象看起来不是解决每个问题的正确方法,部分原因是因为它似乎有很多不必要的开销。这让我鄙视OOP。

在那之后的几年里,在我对我有意义的情况下,我已经成长为喜欢OOP的人。我能想到的最好的例子是我写的最新的网络应用程序。最初它运行了自己的单个数据库,但在开发过程中我决定将其挂钩到另一个数据库以导入有关新用户的信息,以便我可以让应用程序自动设置它们(输入员工ID,检索名称和部门) 。每个数据库都有一组检索数据的函数,它们依赖于数据库连接。此外,我希望明显区分一个函数所属的数据库。对我来说,为每个数据库创建一个对象是有意义的。构造函数完成了建立连接的初步工作。

在每个对象中,事情都是程序性的。例如,每个类都有一个名为getEmployeeName()的函数,它返回一个字符串。此时,我认为不需要创建Employee对象并将名称检索为属性。如果我需要检索关于员工的几个数据,那么对象可能会更有意义,但是对于我需要的少量内容,它似乎并不值得。

答案 17 :(得分:0)

当我从程序化转向面向对象时,我做的第一件事是熟悉静态范围。

Java是开始执行OO的好语言,因为它试图保持对所有不同OO范例的忠实。

程序程序员会查找程序入口和出口点之类的东西,一旦他们能够概念化一次性类的静态范围对他们来说是最熟悉的,那么知识将从那里开始。

我非常清楚地记得灯泡的瞬间。帮助他们理解抽象,实例,静态,方法等关键术语,并且您可能会给他们提供更好地向前发展的工具。

答案 18 :(得分:0)

我是一名专业的OO开发人员,但我的开发团队已经拥有程序开发人员(他们正在开发Matlab代码,所以它有效)。在OO编程中我喜欢的一个概念是对象如何与你的域相关联(http://en.wikipedia.org/wiki/Domain-driven_design - 埃里克埃文斯写了一本书,但它不是一本初学者的书。)

说到这里,我会开始在高层次上展示OO概念。试着让他们设计一辆汽车。大多数人会说汽车有车身,发动机,车轮等。解释这些车与现实世界物体的关系。

一旦他们似乎掌握了这个高级概念,那么我将从它的实际代码部分和继承与聚合,多态等概念开始。