我在哪里可以找到转换为目标代码的过程代码示例

时间:2009-08-28 16:01:01

标签: .net oop

我正试图围绕面向对象的编程。但我遇到了一些麻烦。我(想)我理解为什么OOP是一个'好'设计的一般概念和论据。当我坐下来尝试编写OOP代码时,我的问题出现了。

我倾向于最终得到程序,这些程序要么非常程序化,要么偶尔会把对象扔进去......或者程序对于他们正在做的事情看起来非常冗长和复杂......一切都是对象;但是有许多很多物体和遗传树变得又长又丑。

我一直试图找到的是一些非平凡的例子(我已经看到很多涉及猫,狗和动物的丢失/伪代码......但它们似乎没有帮助的时候我实际上尝试编写需要做某事的东西)设计精良的OOP源代码。理想情况下,我正在寻找能够引导我完成思考过程的东西。就像'好吧 - 这里有一些做XYZ的程序代码。现在,这里有一些非常好的OOP代码可以做同样的事情!'。

由于

4 个答案:

答案 0 :(得分:10)

现实情况是,这种转换通常不是好的面向对象的代码。为什么?因为面向对象的代码不仅仅是将函数转换为方法和数据到成员中。

相反,一个好的对象应该对其所有数据负责,并且只接受方法参数,其中这些参数定义了将要操作的数据。

这意味着没有从过程函数和过程数据结构到面向对象的映射的1:1映射。

看了一眼后,我没有找到任何我在网上关心的例子,所以我只是简单地给出了将程序代码转换为OOP的重构规则。

第一步是简单地将每个模块打包为一个对象。换句话说,只需创建一个包含数据和函数的对象。这对纯粹主义者来说太可怕了,但你必须从某个地方开始。例如,如果您有BankAccount模块,那么您现在将拥有BankAccount对象。

显然,这些功能是将数据从外部调用传递到它们中。在这里,您正在寻找如何内化该数据并尽可能地将其设为私有。目标应该是在构造函数中获取数据(至少是起点)并删除用于手动接收数据的参数,并用对现在私有数据的引用替换它们。使用BankAccount对象,现在可以通过对象上的方法对帐户进行所有访问,并且内部化了实际的帐户数据。

您的许多函数可能返回了数据结构的修改版本:停止直接返回该数据并将这些修改保留在私有结构中。创建访问者属性,在必要时返回您现在的私有数据并将其标记为“过时”(您的目标是使对象成为其数据的主人,并且仅返回结果而不是内部数据)。使用BankAccount对象,我们不再返回实际的帐户数据,但我们有CurrentBalance的属性和AverageBalance(int days)等方法来查看帐户。

最终,您将拥有一组自包含的对象,这些对象与您在设计中使用对象时所做的事情几乎没有相似之处,但至少您可以继续使用新对象进行重构。我的下一步通常是发现通过这种重构创建的对象可以承担很多责任。此时可能已经检测到一些常见线程,您应该创建对象以将这些常见想法重构为。如果我们有BankAccount,我们可能有其他帐户类型,如果我们调整所有这些帐户类型的方法,我们可以将Account作为实现所有共享功能的基类,而BackAccount,SavingsAccount和其他人实现详细信息。

一旦类结构开始成形,现在是时候对转换感觉更好了。重构是一个过程,而不是一个端点,所以我通常会发现我的类结构在不断发展。获得这个目标的一个好处是你的数据是私有的,并通过方法进行操作,因此你可以随着进步越来越自由地重构内部。

使这个看似合理的一件事就是进行良好的单元测试。在对OOP转换进行程序化时,我经常将旧代码保留为“基线”,以便我可以对其进行测试。即,测试可以验证旧程序系统的结果。如果你不匹配,最好找出原因。我发现经常会出现一个错误...但有时你的新清洁代码实际上是在做一些过去错误的事情。

关于创建“太深”的对象树:这可能是对继承过于痴迷的结果。我发现复合通常是一个更好的主意,你实现了多个对象的接口,而不是试图将所有这些功能都集成到一个父对象中。如果您发现自己创建的父对象只是功能集的混合,请考虑通过为每个功能集创建一个接口并实现这些接口来进行简化。

答案 1 :(得分:3)

程序编程人员在启动面向对象编程时经常遇到的问题是继续设计程序并尝试将它们组织为对象。这不起作用。

面向对象编程是一种不同的设计方法;您在整个代码中分发角色和职责的不同方式,而不仅仅是不同的编码方法。

当你越过“狗是一种哺乳动物”的比喻(从未转化为真正的应用)时,我会推荐这本书:Object Design: Roles, Responsibilities, and Collaborations。这是我读到的第一本书,其中我终于得到了为什么我不得不停止查看(在我的情况下)C ++为“C with with classes in in”。

答案 2 :(得分:2)

从C API到C ++ API的一个非常直观的过渡在数据库中发生了很多;因此,对于此示例,我们将快速了解使用MySQL API的不同之处。

我不确定是否可以从这些网站复制代码(不知道它是什么许可证),但是查看the section labeled "Creating a Database"进行C演示,Sample #1进行C ++演示;这两个步骤都是通过编程方式创建MySQL数据库。

在C API中,每个函数的第一个参数是数据库的“句柄”。在C ++ API中,我们使用数据库连接 object ,它使用私有句柄隐式调用C API。

要查看一个非常具体的示例,要在生成查询后执行查询,我们在C中执行:

mysql_query(conn, "create database testdb")

并在C ++中:

query.execute();

这里最大的区别是C ++绑定只能向您显示您需要查看的内容,而在C中您必须非常清楚地了解每个细节。

我认为数据库API是通过示例获取一些OOP原则的好方法,所以希望它们也可以帮助你。

答案 3 :(得分:1)

我知道这是标记的.net,但一个很好的例子来自PHP。在PHP5之前,PHP只是部分面向对象。许多PHP开发人员都有同样的把握OOP的问题。

Zend有一篇非常好的文章here。它应该很容易理解。

如果您觉得需要更好地指导面向对象的设计过程,您可能需要查看麻省理工学院的Open CourseWare,特别是Foundations of Software Engineering(讲义#2)或类似内容。