“ OOP隐藏状态”是什么意思?[关闭]


11

cat-v.org上的许多反OOP咆哮中,我发现Joe Armstrong的一段话提出了一些反对OOP模型的异议,其中之一是:

异议4 –对象具有私有状态

国家是万恶之源。特别应避免具有副作用的功能。

尽管编程语言中的状态是不可取的,但在现实世界中,状态比比皆是。我对银行帐户的状态非常感兴趣,当我从银行存款或取款时,我希望银行帐户的状态能够正确更新。

考虑到现实中存在状态,编程语言应提供哪些设施来处理状态?

OOPL说“隐藏程序员的状态”。状态只能通过访问功能隐藏和看到。常规编程语言(C,Pascal)说,状态变量的可见性由该语言的作用域规则控制。纯声明性语言表示没有状态。系统的全局状态包含在所有功能中,并且来自所有功能。诸如monads(用于FPL)和DCG(逻辑语言)之类的机制用于向程序员隐藏状态,以便它们可以“好像状态无关紧要”进行编程,但在必要时可以完全访问系统状态。

OOPL选择的“从程序员隐藏状态”选项是最糟糕的选择。他们没有揭露状态并试图找到最小化状态滋扰的方法,而是将其隐藏了起来。

这到底是什么意思?我几乎没有底层或程序方面的经验,主要是OOP,所以这可能解释了我对此有多么不熟悉。从更现代的角度来看,现在大多数面向对象的歇斯底里都通过了(至少据我所知),你们认为这种通过的准确性/相关性如何?

谢谢你的帮助。


3
推荐阅读:讨论此$ {blog}
2014年

1
如果您问我,您链接到的文章提出了一些相当糟糕的论点(更不用说写作的质量了)。我不会说太多。
本杰明·霍奇森

1
呸。我越来越多地认为这整个“不变”的东西是一个好主意,开始使人们对宗教产生恶臭。
罗布

3
乔·阿姆斯特朗(Joe Armstrong)公开承认他对OO的反对是基于对OO的确切误解。他现在已经意识到,Erlang实际上是一种深层的面向对象的语言(实际上,它可能是主流使用中最面向对象的语言)。
约尔格W¯¯米塔格

9
为了进一步说明这一点:乔·阿姆斯特朗的rant的archive.org的第一次捕获是在2001年4月。乔在2003年撰写了自己的论文。在撰写论文时,他对OO有了很多了解,他意识到自己已经沦为猎物了。常见的误解是,OO以某种方式与可变状态有关(不是,可变状态是完全正交的)。从那以后,他承认对OO的批评是错误的,具有讽刺意味的是,Erlang实际上是一种面向对象的语言(它具有消息,它具有称为过程的对象,具有封装)。
约尔格W¯¯米塔格

Answers:


32

这到底是什么意思?

在这种情况下,这意味着OOP通过将程序隐藏在远离程序员的位置,但仍通过(泄漏)访问器方法使其可见,从而模糊了程序的状态。有论点是,通过遮盖状态,将使其工作起来更加困难,并由此导致更多错误。

你们认为该段落的准确性/相关性如何?

我认为这是相关的,但误导了。如果您的班级将其状态的概念泄漏给外界,那绝对是一个问题。如果您的班级试图在应由外部世界操纵状态时使状态变得晦涩,则绝对存在问题。虽然这不是整个OOP的失败,但是是该类的个性化设计。我不会说隐藏状态本身就是一个问题-monad始终在函数式编程中这样做。

在最好的情况下,OOP就像函数式编程和过程的最佳结合一样,人们可以使用类,“状态无关紧要”,因为用于保护类不变式的私有状态是隐藏的,但拥有自由使用明确定义的类的公共状态来抽象细节。

OOP是否会使人们更难达到最好的情况?可能吧 “ Java学派”以及整个Shape / Circle / Rectangle或Car的Wheels学派的OO学派可能要比方法本身承担更多的责任。现代的OOP从函数式编程中吸取了很多东西,它鼓励不可变的对象和纯函数,同时不鼓励继承,从而使设计良好的类变得更加容易。


3
全心全意地同意“ java学校”的观点,一点也不喜欢。非常感谢您,如果可以的话,我会投票。
2014年

2
准确地说:单子通常不会隐藏状态,有些单子会隐藏状态(例如IO)。参考他人之间stackoverflow.com/questions/2488646/...
thSoft

2
+1。这是比提问者链接的文章更加平衡和细腻的分析
Benjamin Hodgson 2014年

2
乔·阿姆斯特朗(Joe Armstrong)公开承认他对OO的反对是基于对OO的确切误解。他现在已经意识到,Erlang实际上是一种深层的面向对象的语言(实际上,它可能是主流使用中最面向对象的语言)。
约尔格W¯¯米塔格

2
Jorg-您能张贴乔的跟进链接吗?我会很感兴趣阅读它。还有@radarbob,就对了!
user949300 2014年

2

如果存在多个可变状态而没有单个明确的“所有者”,则对系统进行推理将很困难。这并不意味着对象永远不应该具有可变状态,而是应该以不清楚所有权的方式使用具有可变状态的对象,相反,应该自由传递而不跟踪所有权的对象应该使用一成不变。

实际上,有效的编程经常要求某些对象具有可变状态。但是,这种状态应限于未共享的工作对象。考虑.NET中的IEnumerable/ IEnumerator接口:如果实现了一个集合IEnumerable,它将允许一次读取一项。读取集合的实际过程通常需要跟踪已读取的项目(可变状态),但是的实现中不包含这种状态IEnumerable。相反,IEnumerable提供了一种称为的方法,该方法GetEnumerator将返回一个实现IEnumerator并包含足以允许从集合中读取项目的状态的对象。对象包含这种状态这一事实将不会造成任何问题,如果IEnumerator不共享对象实现

在大多数情况下,最好的模式是混合使用可以自由共享但永远不会被修改(至少在共享之后不会被修改)的对象以及拥有明确所有者并且可以由该所有者自由修改的对象的混合,但永远不会与任何人共享。


什么应该是不变的和什么可以具有可变状态之间的出色区分。读完这篇文章后,我意识到我最近的对象图(比以前更不可变)基本上遵循了该准则,而没有像您所做的那样清楚地陈述。这是您有时听到的“可变状态总是邪恶”的好方法。
Mike支持Monica

@Mike:我认为真正的问题是Java和.NET中的所有对象引用都是完全混杂的;获取或接收对对象的引用的任何代码均可不受限制地与任何其他代码共享。两种框架都没有关于不可共享参考域的任何概念;.NET中的结构和byref都很接近,但是它们在可以做什么或可以阻止外部代码执行方面是相当有限的。无论如何,我会提出一个关于可变状态的基本说法:在12:57 am,一个物体可能同时表示……
supercat 2014年

...现实世界对象的当前状态以及该对象在上午12:57处的状态。如果对象的真实状态发生变化,则对象将无法再同时代表这两者。有时有必要使对象继续代表上午12:57的状态,有时还需要代表当前的状态。但是,如果当前状态发生更改,则无法保持12:57 am状态与当前状态之间的关系。
supercat 2014年

0

冒着超越回答问题的风险,很容易看到OOP理念的缺陷,但是我倾向于认为一个理念的力量体现在它被滥用的能力上。

毕竟,每个人都有自己喜欢的语言,用“非常非常强大”这样的术语来描述,这表示他们真的很喜欢它。但是计算通用性的奇迹在于,无论一种语言多么辉煌,如果它真正强大,它就可以模拟汇编语言。如果可以的话,有人会看到的。(并不是说汇编语言有什么问题。)

我对OOP潮流的个人感觉是,它代表了人们对软件工程/计算机科学教育的发展。他们在认为与数据结构有关的某个级别上受挫。类,继承,容器,迭代器,哈希映射,属性,状态隐藏等-与数据结构有关-越多越好。

我个人希望看到一个新的水平,在这个水平上,人们将通过语言角度学习解决问题。他们将了解特定领域语言的概念,以及如何轻松制作它们并使它们成为解决问题的组成部分。说数据结构一种语言并没有错。人们应该具有这种语言设计技能,因此他们不仅会对此感到无所适从。

接下来,我希望看到人工智能重新焕发活力。我希望看到程序员超越字节和线程,虚函数表和CUDA,而转向如何使机器推理,学习和创建。我知道这在领域的各个角落已经取得了很大进展,但范围还不够广泛。


1
“如果它真的很强大,它可以模拟汇编语言”-您在powerful此处交换了正确的定义。当别人说的时候powerful,他们谈论的是它允许程序员抽象的程度如何,这与计算能力是一个不同的故事。
Phil

@Phil:抽象是其中一个词:)
Mike Dunlavey 2014年

没事 你在说单词。我在说想法。该词的第二次和第三次用法power含义不同。请不要误导。
2014年

顺便说一句,如果您有兴趣的话,请查看Racket,它与您在第4段中所说的方法有点接近(使程序员能够将语言带到他们所遇到的问题的水平,而不是让他们将问题归结为语言的固定结构集)。它可以超越经典的Lisp / Scheme,以防万一有人第一次看到它时有这种印象。
菲尔(Phil)

0

可访问性不是OOP的功能,它特定于Java和Microsoft dotNET之类的实现。定义OOP的主要特征是多态。

无论如何,通过隐藏对象状态,无法创建有意义的API。演示是现实世界中OOP的重要组成部分。那些不同意的人可能对软件行业抱有非理性的敌意,从我的观点来看,这与他们的观点无关。

您所链接的网站之所以臭名昭著,是因为人们对新技术的思想刻板和批评。有些人就是不明白。


应该存在一个对象以保护其建模概念的不变性。表示是一个完全独立的关注点,不能由同一对象有效且可维护地处理,因为一个对象无法理解它可能随时间和空间呈现的所有各种方式。如果您的目标是通用且可维护的对象,则必须通过其他机制来处理演示,例如事件流和物化视图。对象应该更改的唯一时间是修改其概念或更改其不变性。
安德鲁·拉尔森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.