在尝试将方法放在正确的位置等时,迷失在OOP joungle中

时间:2009-10-26 13:00:27

标签: oop

这并不是说我不理解OOP的概念,以及在什么时候应该做什么,但有时我只是在精神上迷失了。

一个例子还有什么好处?所以我需要将文件下载到临时路径,因为不相关的原因,我决定不使用dot net的常规方法来获取临时路径。所以我为这个string GetTempFileSafe(string extension, out FileStream)编写了自己的方法,很好,不是吗?但是,嘿,等一下,这不是这个方法的正确位置......这个方法可能用于其他事情。它需要是一个静态的公共方法。但是哪里?好吧,我想我需要为它打开一个新的静态类。希望我能在其他日子里添加更多方法。

所以我定义了public static class FileStreamUtils \\one hell of a name huh?,并添加了我的方法。但请坚持......这堂课应该在哪里?基本上我可以在任何项目中使用......它与这个特定的项目无关。所以我打开了一个全新的库,我称之为MyUtils

我用我的一个静态方法将静态类添加到其中,构建了库,添加了dll作为对原始项目的引用......以及它。 (注意方法调试比较困难,因为我使用的是dll而不是原始代码)

现在不要误会我的意思。我真的很喜欢OOP的概念和整洁,但有时它只会让我精神疲惫......也许是因为我全身心投入工作。

那你觉得怎么样?我只是无所事事地哭泣,像开设公用事业图书馆这样的事情大多只做一次,我只需要改变态度吗?或者你认为有时最好不要那么坚持整洁(例如,在我的情况下,只是在那里生活方法,并且以防我将再次需要它,将它移动到公共使用)?

非常感谢你。并且,如果你以某种方式成功找到投票给我的理由,没问题,但请发表评论,所以我不能在这里重复我的错误。

6 个答案:

答案 0 :(得分:5)

我总是对罗伯特·格拉斯在这些情况下Rules of Three的观点感到震惊。在您有三个功能适合的地方之前,不要担心重复使用。我总是喜欢在我第一次需要的时候编写这个函数。请注意,我第二次复制它。第三次完成重用工作(将其重构为实用程序库)。

答案 1 :(得分:2)

重构很好。虽然您可能不想从阅读this thesis about refactoring开始,但这是一个很好的阅读并将其全部放在一边。您可能还想查看https://stackoverflow.com/questions/441896/how-to-be-master-in-c-and-object-oriented-technology的答案,其中有一本关于重构的书。

最重要的是,您不必将所有代码放在正确的位置并以正确的方式组织它。做一些现在足够好的事情,在可能的重构列表中记下它,当你有时间时,浏览列表并重新审视代码。也许足够好,足够好。如果没有,请帮助代码进一步发展。

答案 2 :(得分:1)

将内容添加到Jason's answer

此外,这就是每日会议,结对编程,代码审查的原因。在这些非正式会议中,您说明了您为团队所做的事情(创建了一个临时文件),因此如果有人已经完成了,或者他们也需要它,您就知道必须重构到实用程序库中。否则你就把方法留在那里。

我知道你提到你独自工作,但沟通是避免代码重复和许多code smells的关键,所以这个建议主要针对团队,而不是独立的程序员。

答案 3 :(得分:0)

说实话,你所做的并不是错误的。然而,你所做的和我所看到的很多人都在为应该如何完成工作而烦恼,然后把重点放在手头的工作上,制作一个很酷的软件来做一些很酷的功能。

在你的特殊情况下,你不需要一个类库,因为只有一个函数,所以我只是把它放在一个Helper类中。但是,如果您计划添加许多有用的函数,那么类库是一遍又一遍地使用代码的好方法。但是不要向不需要它的应用程序添加太多层。

答案 4 :(得分:0)

我的一般经验法则是,每次我编写一个至少包含一个参数的静态方法时,都会产生代码气味。

在OO中,操作应该绑定到对象,因此最好将方法移动到其中一个对象,而不是从辅助库中操作一个或多个对象。

我知道如果你正在使用BCL的内置类型,这是不可能的,但气味应该让你开始考虑替代品。

让我们看看你的例子:你不能将GetTempFile安全添加到System.String或FileStream,但是任何参数都代表一个隐藏的概念,可以更好地建模为一个对象吗?

虽然我不知道你的例子中是否属实,但“扩展”听起来像是一个概念,所以为什么不定义这样的Extension类:

public class Extension
{
    private readonly string extension;

    public Extension(string extension)
    {
        // Guard Clauses go here
        this.extention = extension;
    }

    public string GetTempFileSafe(out FileStream)
    {
        // implementation goes here, using this.extension...
    }
}

下一步,您可以通过将生成的字符串和FileStream封装在新对象中来更改此API以删除out参数。

答案 5 :(得分:0)

显然你说的是C#,我不知道,这些天我主要是一个Java人,所以也许有技术上的差异,但......

在Java中,您可以将类划分为“包”。您可以同时编译多个包,在IDE中将它们保存在一起,但也很容易将它们分解出来。

当我写一组我认为我可能想要重复使用的类时,我将它们放在一个单独的包中。除非我真的想在其他地方使用它们,否则我仍将它们作为同一项目的一部分。如果发生这种情况,那很好,我将包复制到它自己的项目并从中构建一个库。

因此在开发期间,它仍然是同一个项目的一部分,仍然在同一个工作区等,因此易于调试并且通常可以跟踪。

如果我从未在其他地方使用它,请找到,没有伤害。

如果我在其他地方使用它,那么有时候我很懒,只需将包复制到新项目中。有时我真的把它变成一个独立的库。 (当我说“偶尔”时,我认为在现实生活中我的意思是我在过去的十年中已经完成了两次。)

正如我所说的,我不知道C#是如何分组的,是否有一种简单的方法可以将一组类分解成一些方便的“单元”。