Parnas的信息隐藏理论与OOP滥用的反思

信息隐藏这一概念是
大卫·帕纳斯(David Parnas)在1971年提出的。
随后,在编程历史上留下深远影响的经典论文,

1972年的《On the Criteria To Be Used in Decomposing Systems into Modules》(关于将系统分解为模块时应使用的标准)问世。

这篇论文是软件工程领域的里程碑之作,非常值得一读。

这篇论文提出了在将系统分解为模块时的划分标准。

这篇论文之所以在编程历史上非常重要,是因为在此之前,
人们通常基于处理步骤,即以绘制流程图的控制流为基础进行分解。

然而,这种传统方法导致了高耦合度(Coupling)低内聚度(Cohesion) ,使得软件难以维护。
因此,这篇论文提出了一种替代方案——“信息隐藏”(Information Hiding)。

在这篇论文中,对“模块”的定义进行了说明:

  1. 那些可能发生变更的设计决策应该被隐藏在模块内部。
  2. 模块应该通过明确定义的接口与其他模块进行通信。

也就是说,每个模块的内部操作、数据结构和算法对外部应该是不可见的,
只能通过公共接口进行交互。

在这篇论文中,帕纳斯(Parnas)以一个名为 KWIC索引系统 的系统为例,展示了两种分解方式。
第一种是过程式分解 方法:

  1. 输入(Input)-> 循环移位(Circular Shift)-> 字母排序(Alphabetizing)-> 输出(Output)(可以理解为输入 -> 转换 -> 排序 -> 输出的过程)

如果模块按照过程式分解,当数据表示或设计决策需要更改时,就会导致多个模块需要修改的问题。

现在进入重点,第二种方法是信息隐藏分解 (Information-Hiding)。
在这种方法中,模块的设计决策单位包括数据存储方式、如何进行行变换(shift)、以及如何实现排序等内容,并以此为依据将系统划分为“模块”。
模块的内部实现和数据格式对外部是隐藏的,只通过接口提供必要的功能或数据。
即使某个模块的数据结构或排序方法发生了变化,只要接口保持不变,对其他模块的影响几乎可以忽略不计。

那么,究竟什么是模块?如果以信息隐藏为核心来定义,模块是可以轻松在其他项目或情境中重复使用的。
也就是说,由于变更被限制在模块内部,程序修改时错误减少,维护变得更加容易。

通过使用信息隐藏进行分解的结果是,
在保持稳定接口的同时,以功能单位定义模块,可以轻松地在其他项目或情境中重复使用或修改。
这篇论文被认为是奠定了现代软件工程基础的重要论文之一。

从这篇论文开始,我们的编程方法论从过程式 转向了结构化 (当然,还有许多其他论文作为支撑)。
虽然在中国可能不太一样,但在海外,这篇论文常被用来批判OOP(面向对象编程)。
事实上,OOP也无法完全脱离这篇论文的影响,但为什么这篇论文会被视为批判OOP的案例呢?
因为在过去,OOP被滥用的情况很多,这篇论文经常被引用为反驳错误OOP实践的依据。

错误使用的OOP表现为:

  • 不必要地将方法或字段暴露为public
  • 由于继承导致内部实现被暴露,
  • 仅仅形式上实现了封装,却误以为这就是“信息隐藏”。

这种对OOP的误解受到了批评,认为它违背了Parnas在这篇论文中的初衷。
也就是说,如果把类简单理解为功能块(通常程序员这样描述),那么这与Parnas所批评的“阶段中心分解”并无本质区别。
换句话说,许多编程书籍和讲师介绍的

类(Class)= 数据(Data)+ 方法(Method) ”的简单组合是一种错误且形式化的理解(Incorrect and Formal Approach)。
真正的**类(Class)**应该是

  • 领域(Domain)+ 概念(Concept) + 负责的行为/规则(Responsibilities/Rules)+仅暴露必要的接口(Expose Only Necessary Interfaces) + 隐藏内部实现(Hide Internal Implementation)
  • 这才是这篇论文所追求的真正意义上的信息隐藏(True Information Hiding)。

因此,错误使用的OOP未能实现良好的信息隐藏。
为了克服这一问题,并解决信息隐藏不当的问题,现代OOP提出了一个重要的建议:
“优先使用组合而非继承。
(Composition over inheritance)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值