艾伦·凯(Alan Kay)在“ Smalltalk的早期历史”中的“分配”是什么意思?


47

我一直在阅读《 Smalltalk的早期历史》,并且提到了“分配”,这使我质疑其含义:

尽管OOP来自许多动机,但其中两个是核心。大型方案是为包含细节隐藏的复杂系统找到一种更好的模块方案,而小型方案是找到一种更灵活的分配方案,然后尝试将其彻底消除。

(从1960-66年开始-早期的OOP和六十年代的其他形成性思想,第一部分)

我从Simula得到的是,您现在可以用目标替换绑定和分配。您希望任何程序员做的最后一件事就是内部状态混乱,即使以图形方式呈现也是如此。相反,应该将对象呈现为更适合用作动态组件的更高级别行为的站点。(...)不幸的是,当今所谓的“面向对象程序设计”中的大部分只是带有奇特构造的旧式程序设计。许多程序现在都通过“昂贵的附加程序”来完成“分配样式”操作。

(摘自“面向对象”样式,第IV节)

我将目的解释为对象是外观,而目的是在对象上设置实例变量(即“赋值”)的任何方法(或“消息”)都违反了目的,我是否正确?第四节中的以下两个陈述似乎支持了这种解释:

一起使用的四种技术-持久状态,多态性,实例化和作为目标的方法-占据了很大的力量。这些都不要求使用“面向对象的语言”-ALGOL 68几乎可以转变为这种样式-OOPL只是将设计师的思想集中在一个特定的富有成果的方向上。但是,正确执行封装不仅是对状态抽象的承诺,而且是从编程中消除面向状态的隐喻的承诺。

...和:

分配语句(甚至是抽象的语句)表达了非常低级的目标,需要更多的目标才能完成任务。通常,我们不希望程序员弄乱状态,无论是否模拟。

可以这样说,鼓励不透明,不可变的实例吗?还是不鼓励直接改变状态?举例来说,如果我有一个BankAccount类,它的确定有GetBalanceDepositWithdraw实例方法/消息; 只需确保没有SetBalance实例方法/消息?

Answers:


86

基本思想(受Sketchpad的影响)是,大多数变量/值彼此之间是动态的关系(由对象的内部维护),因此能够从外部直接重置值是危险的。因为(无论如何,在Smalltalk中)至少需要一种设置方法,因此可以通过内部方法来调停外部设置动作,以保持所需的相互关系。但是,大多数使用setter的人只是简单地使用它们来模拟对内部变量的直接分配,这违反了实际OOP的精神和意图。

但是对象确实具有时间变化的“世界线”。可以将其视为对象的版本的“历史”,其中“关系”是一致的。此方案中没有竞争条件……仅当对象稳定且不再计算时,该对象才可见。这就像硬件中的两相时钟。(来自Strachey的想法,与McCarthy的想法不同,并受Lucid的影响。)

最好的祝愿,

艾伦·凯


2
@ alan-kay:谢谢!我可以在你的论文中引用这个吗?
Olivier Dagenais

2
控制副作用,或者像许多语言一样,知道如何控制副作用。但是似乎还没有找到它。:)
Mathk 2011年

@OlivierDagenais虽然我确定Alan会很高兴(他看起来是一个很棒的家伙),但是SE答案是CC许可的,因此寻找SE问题和答案是完全合法的。
韦恩·沃纳

两相时钟?这类似于Excel或React.JS中的“观察者”模式和数据流模式,其中对象传播所有更改以保持约束。
aoeu256

21

我知道艾伦已经回答了这个问题,因此进一步答复似乎毫无意义。但是,艾伦并没有回答您的所有问题。

尤其是:

可以这样说,鼓励不透明,不可变的实例吗?还是不鼓励直接改变状态?例如,如果我有一个BankAccount类,可以使用GetBalance,Deposit和Withdraw实例方法/消息;只是确保没有SetBalance实例方法/消息?

答案是您没有使用高阶行为来构造程序。现实世界中的金融服务系统不应在BankAccount类上使用存款方法,因为这根本不是银行在发明计算机之前的工作方式!发明自动取款机时,它们必须自动实现柜员在银行所做的工作。柜员的作用是通知客户其帐户状态。为此,仅允许客户以几种方式与柜员互动,例如将存款单传递给柜员。

通过直接验证这些对象(柜员,存款单等),根据系统中实体所传递的消息来构造问题域。

帐户本身起着作用-帐户的字面意思是与资产,负债,收入或费用相关的财务流入和流出帐户。会计系统或会计记录,保留和复制这些流,并在某个时间点告诉您帐户的财务状况。出纳员的最新报告可以被认为是“现在”,但实际上并非如此:这确实是会计师在某个时间点所描述的财务状况。当您去银行时,它只是具有“立即”的幻想,因为通常您是唯一被授权进行付款的人。100年前尤其如此,但是今天许多人都使用自动付款,

为什么这很重要?好吧,问问自己,记录交易需要做什么:

客户对自己所做的一切都有自己的内部审核日志,包括来自银行的收据。同样,世行保留自己所做所有工作的内部审计日志。银行总是复式记帐,这意味着它们在总帐及资产负债表记录交易。这使银行可以进行对帐并确保在给定的财务期间(每天,每周,每月,每月,每季度,每年,每两年一次)结帐时,没有虚假条目。这也表明记录的记录应该是幂等的。这意味着,如果我们要编写一个列出所有唯一事务的程序,即使在内部审计日志中存在虚假重复,我们也可以这样做,因为我们将幂等事务标识符嵌入了日志消息中。

鉴于自动付款功能可以对您的帐户进行借记和贷记,因此会计师也可以为您进行预测似乎很有意义。这就是计算机对会计系统的影响的认识。因此,有人发明了一种称为“ 资源-事件-代理”的会计系统方案,该方案不仅与过去有关,而且与未来有关,并且比以前更细粒度地估计现金流量,因此更加内联。从本质上讲,REA仅比传统会计系统具有更多的元数据,从而可以实现更好的报告和业务分析。例如,“价值链”分析和“供应链”分析对于经典会计而言并非易事。

同样,Agoric计算智能合约将思想从市场机制引入计算。重要的是,当您提供存款单时,还应提供支票或钱包进行存款。由于收到支票到实际进入您的帐户之间需要一定的时间,因此您需要一种安全的方式来管理货币。事实证明,对象功能是实现分布式安全货币的自然方法。它们可以用来确保爱丽丝(Alice)在写给鲍勃(Bob)支票后,通过撤回她所有的资金来欺骗鲍勃(Bob)。


感谢您消除OOP的所有常见BankAccount玩具示例。
akuhn

虽然总体上您的回答是很好的(很少有人知道一个帐户不是余额而是交易清单,所以谢谢您),但是您不会得到两次输入会计的权利。重复输入的要点是,帐户的每个借方或贷方(即交易列表)都有对应的其他帐户的贷方或借方,以进行匹配。例如,如果您向客户借入¥108(即,客户给了您这么多钱),您会在收入帐户中记入¥100,在您的“欠税”帐户中记入¥8,以匹配该借项并显示出钱的去向(或应该去)。
Curt J. Sampson
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.