OOP 对小脚本有意义吗?

Does OOP make sense for small scripts?

提问人:Mad Scientist 提问时间:6/15/2010 更新时间:6/15/2010 访问量:5890

问:

我主要用python编写小脚本,大约50-250行代码。我通常不使用任何对象,只是简单的过程编程。

我知道 OOP 基础知识,并且我以前在其他编程语言中使用过 object,但对于小脚本,我看不出对象会如何改进它们。但也许这只是我对 OOP 的有限经验。

我是否因为没有更努力地使用对象而错过了什么,或者 OOP 对于小脚本没有多大意义?

Python OOP 脚本

评论

22赞 Tom 6/15/2010
不确切地知道你的情况/背景,但尽量不要仅仅因为它出现在杂志封面上就强迫使用它。
0赞 Alex Gordon 6/15/2010
没坏就别修
1赞 Fanatic23 6/15/2010
在这里,将代码维护需求作为决定性因素。

答:

3赞 Jesse Jashinsky 6/15/2010 #1

就你而言,我想说的是,只有当 OOP 使脚本更具可读性和可理解性时,它才会有所帮助。如果没有,您可能不需要打扰。

28赞 JasCav 6/15/2010 #2

面向对象编程虽然对于将系统表示为真实世界的对象很有用(并希望使大型软件系统更容易理解),但并不是每个解决方案的灵丹妙药(尽管有些人教了什么)。

如果您的系统不能从 OOP 提供的内容(例如数据抽象、封装、模块化、多态性和继承)中受益,那么承担执行 OOP 的所有开销就没有意义了。但是,如果您发现随着系统的发展,这些事情对您来说越来越重要,那么您可能需要考虑转向 OOP 解决方案。

编辑:作为更新,您可能想前往维基百科阅读有关对OOP的各种批评的文章。请记住,OOP 是一种工具,就像你不会在所有事情上都使用锤子一样,OOP 也不应该在所有事情上都使用。考虑最适合这项工作的工具。

5赞 omermuhammed 6/15/2010 #3

OOP 是一种管理代码复杂性的工具,50-250 行代码很少复杂。我写的大多数剧本主要是程序性的。所以是的,对于小脚本,只需使用过程编程即可。

请注意,对于非常复杂的脚本,OOP 可能更相关,但仍然没有硬性规定对它们使用 OOP。这是个人喜好的问题。

4赞 Mike Atlas 6/15/2010 #4

使用正确的工具完成正确的工作。对于不需要复杂数据结构和算法的小型脚本,面向对象的概念可能没有用处。

9赞 aviraldg 6/15/2010 #5

如果您打算独立使用该脚本,则不可以。但是,如果您计划使用它并重用其中的一些,那么是的。在第二种情况下,最好编写一些提供所需功能的类,然后使用代码进行条件运行 () 以执行脚本的“脚本”版本。importif __name__=='__main__':

评论

3赞 Michael Mathews 6/15/2010
我经常发现自己希望我把一个简单的脚本做得更面向对象,因为我后来想借用它的某些部分来处理类似的问题。
1赞 aviraldg 6/15/2010
@Xiong :我真的不知道,但出于某种原因,我发现自己对公开的类比公开的函数更舒服。也许是因为使用函数,你最终会暴露所有模块级变量......
1赞 6/15/2010
@Michael:您可以随时根据需要进行重构;这通常比凝视水晶球以查看如何重用它要好。
2赞 Rishav Rastogi 6/15/2010 #6

OOP 只是另一种范式。很多问题都可以使用程序或OOP来解决。

当我在编写的代码中看到明显需要继承时,我会使用 OOP,它更容易管理常见行为和常见属性。

它有时使它易于理解和管理。即使代码很小。

7赞 Jacob Mattison 6/15/2010 #7

我的经验是,任何超过几十行的纯程序脚本都很难维护。首先,如果我在一个地方设置或修改一个变量,然后在另一个地方使用它,而这两个地方不能放在一个屏幕上,麻烦就会接踵而至。

当然,答案是缩小范围,使应用程序的不同部分更加封装。OOP 是实现此目的的一种方法,也是对环境进行建模的有用方法。我喜欢OOP,因为我发现我可以在精神上从思考特定对象的内部如何工作,跳到思考对象将如何协同工作,并且我保持理智。

但是,OOP 肯定不是使代码更好地封装的唯一方法;另一种方法是一组名称良好的小型函数,这些函数具有精心定义的输入和输出,以及适当调用这些函数的主脚本。

33赞 Alex Martelli 6/15/2010 #8

我使用任何最适合手头问题的范式——无论是程序的、OOP、功能的......程序大小不是一个标准,尽管(稍微差一点)一个更大的程序可能更有可能利用 OOP 的优势——一个类的多个实例、子类化和重写、特殊方法重载、OOP 设计模式等。这些机会中的任何一个都可能完全发生在一个小脚本中,只是在更大的脚本中出现的可能性更高一些。

此外,我讨厌这种说法,所以如果自然过程方法需要它,我几乎总是会改用 OOP——即使唯一的优点是能够使用限定名称而不是需要 .globalglobal

一般来说,绝对没有必要“更努力地尝试”——只要问问自己“这里是否有机会使用(a)多个实例(等等)”,它很快就会成为第二天性,也就是说,你会发现机会,而不需要每次都有意识地提醒自己去寻找它们,你的编程就会因此而改进。

评论

2赞 Dominic Bou-Samra 6/20/2010
Alex,我一直在写一个简单的 Chip8 模拟器,我发现自己想知道使用 global 是否是正确的方法。我将它们用于存储器、堆栈、通用寄存器、输入寄存器和定时器等。实际上,我认为全球化是正确的方式。OO会让它变得复杂,而且考虑到实际上只有一个级别的范围在起作用,拥有全局的副作用不会是负面的。你觉得怎么样?
7赞 Alex Martelli 6/21/2010
@Dominic,我不同意——什么并发症?!将 Memory、Stack 等作为实例属性,自然会提供非常简单和紧凑的方法(例如)在模拟运行过程中保存和恢复状态(只是!),“拍摄快照”(),以便您以后可以进行比较以准确查看某个指令序列做了什么(或通过恢复快照来“撤消”它们),等等 -- 大量额外的内容, 几乎不需要任何额外的努力,就具有有用的功能!picklecopy.deepcopy
0赞 Dominic Bou-Samra 6/21/2010
嗯,我从来没有想过使用复制和拥有撤消/保存游戏功能。看起来我使用全局的案例刚刚消失了:D
1赞 zifot 6/15/2010 #9

首先 - 你说的对象是什么意思?在 Python 中,函数是对象,您很可能正在使用它们。:)

如果你所说的对象是指类及其实例,那么我会说一些显而易见的事情:不,没有理由说使用它们本身就能使你的代码变得更好。在小脚本中,复杂的OO设计不会带来任何杠杆作用。

2赞 Sherwin James 6/15/2010 #10

OOP 的另一个好处是传达意图(无论是向其他开发人员、经理还是将来的某个时候您自己传达)。在我看来,如果脚本足够小,可以用几句话完全传达,那么 OOP 可能就没有必要了。

0赞 S.Lott 6/15/2010 #11

“脚本”的意思是“顺序的”和“程序的”。这是一个定义。

脚本处理的所有对象都是对象。所有编程都涉及对象。这些对象已存在于编写脚本的上下文中。

某些语言允许您清楚地识别对象。有些语言不能清楚地标识对象。对象总是在那里。这是一个语言是清晰还是晦涩的问题。

由于对象总是在那里,我发现使用一种可以清楚地识别对象、它们的属性、方法和关系的语言是有帮助的。即使对于简短的“脚本”,我发现显式对象和面向对象语言也有帮助。

关键是这个。

“过程”、“脚本”和“OO”之间没有有用的区别。

这只是重点的转移。对象总是在那里。世界本质上是面向对象的。真正的问题是“你是否使用了一种使对象显式的语言?

评论

0赞 ShinTakezou 6/15/2010
嗯;我不知道根据定义,“脚本”的意思是“顺序的”和“程序的”(即使不能在程序、脚本和OO之间做出有用的区分);似乎你的答案谈到了一种哲学观点(Weltanschauung):物体无处不在。从哲学上讲,它可能是正确的,但它如何应用于编程,其中“对象”是以某种方式定义的,因此你不能像调用对象一样调用“处理器寄存器”对象如果你说一切都是对象,那么抽象的层次和层次就会消失。astring a
0赞 S.Lott 6/15/2010
@ShinTakezou:处理器寄存器是一个对象。通常不会用类定义形式化,但它是一个对象:唯一标识、状态等。它怎么不是一等对象?编程语言强加了哪些基础寄存器尚不具备的属性?
0赞 S.Lott 6/15/2010
@ShinTakezou:对象抽象的层次和层次。对象层层叠叠,有复合对象、Facade 对象和许多其他增加抽象的设计模式。还有一些不是很抽象的低级对象。而且有些非常糟糕的对象具有设计不佳的纯过程 API。
0赞 S.Lott 6/15/2010
“文字”是指书面的(具体地说,“刻字”)。写作是有顺序的。程序是连续的。这都是一体的。脚本、序列、程序。
0赞 ShinTakezou 6/15/2010
“我不知道'脚本'意味着[...]”中没有讽刺意味;关于对象...是的,所以现在我正在用我的对象在对象上进行 objeting(我的意思是:我正在用我的数字在键盘上写字)。我说过:在(OO)编程中,对象是定义的,具有“属性”,其他“东西”(不要混淆2个不同的含义)没有,因此不能称为对象(以OO方式);如果你选择“对象”的一般含义,一切都是对象(也是 CPU 注册),但你正在进入一个我和计算机之间没有区别的水平,因为我们都是对象,你误解了(故意?
2赞 danatel 6/15/2010 #12

对几百行代码使用 OOP 几乎没有意义。但是,如果你的脚本很有用,它可能会增长得相当快,因为会添加新功能。如果是这种情况,最好开始编码 OOP 方式,从长远来看,这将是有回报的。

1赞 back2dos 6/15/2010 #13

OOP 是关于在模块化编程之上添加多态性会得到什么。
后者都提倡低耦合、封装、责任分离和其他一些概念,这些概念通常产生代码,这些代码是简短的、富有表现力的、可维护的、灵活的、可扩展的、可重用的和健壮的。

这与其说是关于大小的问题,不如说是关于软件生命周期的长度。如果你编写任何代码,无论它有多短,只要它足够复杂,你不想重写它,当你的需求发生变化时,它满足上述标准是很重要的。

OOP 使模块化编程更容易,因为它已经建立了实现模块化编程所提倡的概念的解决方案,并且多态性允许通过依赖注入实现非常低的耦合。

我个人认为使用 OOP 来实现模块化(尤其是可重用性)更简单,但我想,这是一个习惯问题。

用一句话来形容。OOP 不会比过程编程更好地帮助您解决给定的问题,而是产生一个更容易应用于其他问题的解决方案。

0赞 Anthony 6/15/2010 #14

作为一个做很多脚本的人,如果你觉得你的代码可能在某个时候超过250行,那就开始说哎呀。我使用了很多 vba 和 vbscript,我同意任何低于 100 行的内容通常都非常简单,花时间计划一个好的 oop 设计只是一种浪费。

话虽如此,我有一个剧本大约有 500 行 +,回想起来,因为我没有这样做,哎呀,它很快就变成了一团乱七八糟的意大利面。所以现在任何超过 200 行的东西,我都会确保我提前有一个好的 oop 计划

1赞 Wayne Werner 6/15/2010 #15

这真的取决于剧本是什么,它在做什么,以及你对世界的看法。

就我个人而言,在脚本完成 20-30 行代码后,我通常可以找到一种 OOP 对我更有意义的方法(尤其是在 Python 中)。

例如,假设我正在编写一个解析日志文件的脚本。好吧,从概念上讲,我可以想象这台“日志解析器”机器......我可以把所有这些纸扔进去,它会对它们进行分类,从一些页面上切下部分,然后将它们粘贴到另一页上,最终递给我一份漂亮的报告。

然后我开始思考,好吧,这个解析器是做什么的?好吧,首先他是(是的,解析器是他。我不知道我的程序中有多少是女性,但这个绝对是男性)要阅读页面,所以我需要一种称为页面阅读器的方法。然后,他将找到所有与我们正在使用的新 Frobnitz 过程相关的数据。然后,他将把所有关于 Frobnitz 过程的引用移动到 Easter Bunny 图的旁边。哦,所以现在我需要一个 findeasterbunny 方法。完成此操作后,他将获取其余的日志,删除每 3 个单词,并颠倒文本的顺序。所以我也需要一个和一种方法。因此,空 shell 类如下所示:thirdwordremovertextreversal

class LogParser(Object):
    def __init__(self):
         #do self stuff here
    def pageReader(self):
         #do the reading stuff here, probably call some of the other functions
    def findFrobnitz(self):
         pass
    def findEasterBunny(self):
         pass
    def thirdWordRemover(self):
         pass
    def textReversal(self):
         pass

这是一个非常人为的例子,老实说,我可能不会使用 OOP 来处理这种情况......但这实际上只取决于我在那个特定时刻最容易理解什么。

10赞 Blessed Geek 6/15/2010 #16

哎呀,一个不幸的习惯是 Objectophrenia——在我们编写的每一段代码中看到对象的错觉。

之所以会发生这种情况,是因为我们妄想相信统一对象定理的存在。

你写的每一段代码,你开始把它看作是对象的模板,以及它们如何适应我们的个人方案。尽管这可能是手头的一个小任务,但我们还是被这个问题所诱惑——我是否可以将其放入我的类存储库中,以便将来使用?我是否在这里看到一个模式,其中包含我以前编写的代码以及我的对象千里眼告诉我有一天我会编写的代码?我可以将我现在的任务结构化为这些模式之一吗?

这是一个令人讨厌的习惯。通常,最好不要拥有它。但是,当你发现你编写的每一段代码都以某种方式落入模式中,并且你重构/重新调整这些模式,直到它满足你的大部分需求时,你往往会获得一种满足感和成就感。

当程序员产生妄想症(强迫性、强迫性、面向对象障碍)并且没有意识到模式存在例外时,问题就开始出现,并且试图过度操纵模式以涵盖更多情况是错误的。这就像我小时候痴迷于每天早上吃早餐时试图用黄油或果酱完全覆盖一块面包。有时,最好把面向对象的感知抛在脑后,快速而肮脏地执行手头的任务。

公认的工业格言 80-20 可能是一个很好的衡量标准。以与通常感知不同的方式使用这句格言,我们可以说 80% 的时间都有面向对象的感知。20% 的时间 - 快速而肮脏地编码。

沉浸在物体中,但最终你必须抵制它吞噬你。

你可能还没有做足够的编程,因为如果你做了,你会看到你已经完成的所有模式,你也会开始相信你还没有应用的模式。当你开始看到这种 objectophrenia 异象时,是时候小心不要被它们吞噬了。

评论

0赞 Justin L. 6/15/2010
不幸的是,我的 objectophrenity 已经延伸到我的日常、非编程生活中:(
0赞 Greg S 6/18/2010
+1 对于这篇有趣且略带恐惧的文章......Objectophrenia ;-)
4赞 Norman Ramsey 6/15/2010 #17

我是否因为没有更努力地使用对象而错过了什么,或者 OOP 对于小脚本没有多大意义?

对象为你购买封装重用(通过继承)。在编写小脚本时,两者都可能非常有用。当你写了一组类似的脚本,或者你发现自己反复更改你的脚本时,也许你应该考虑对象可能在哪些方面有所帮助。