【问题标题】:A brilliant example of effective encapsulation through information hiding?通过信息隐藏进行有效封装的绝妙例子?
【发布时间】:2009-03-11 18:15:06
【问题描述】:

"抽象封装是互补的概念:抽象侧重于对象的可观察行为...封装侧重于实现这一点行为...封装通常是通过信息隐藏实现的,这是隐藏对象的所有不影响其基本特征的秘密的过程。” - Grady Booch 在面向对象分析和设计中

您能否向我展示一些极具说服力的示例,说明通过信息隐藏进行封装的好处?

【问题讨论】:

    标签: language-agnostic oop encapsulation abstraction information-hiding


    【解决方案1】:

    我的第一个 OO 课中给出的例子:

    想象一下媒体播放器。它抽象播放、暂停、快进等概念。作为用户,您可以使用它来操作设备。

    您的 VCR 实现了此接口并隐藏封装机械驱动器和磁带的详细信息。

    当媒体播放器的新实现到来时(比如使用光盘而不是磁带的 DVD 播放器),它可以替换媒体播放器中封装的实现,并且用户可以像使用 VCR 一样继续使用它(播放、暂停等相同的操作)。

    这就是通过抽象实现信息隐藏的概念。它允许在用户无需知道的情况下更改实现细节,并推广低coupling 的代码。

    【讨论】:

      【解决方案2】:

      *nix 将字符流(磁盘文件、管道、套接字、tty 等)抽象为单个实体(“一切都是文件”)模型允许将各种工具应用于广泛的范围数据源/接收器的方式,如果没有封装是不可能的。

      同样,各种语言中的流概念,对列表、数组、文件等进行抽象。

      此外,数字之类的概念(对整数、六种浮点数、有理数等进行抽象)可以想象,如果更高级别的代码被赋予尾数格式等并让其自生自灭,这将是一场多么可怕的噩梦.

      【讨论】:

        【解决方案3】:

        我知道已经有一个公认的答案,但我想再抛出一个:OpenGL/DirectX

        这些 API 都不是完整的实现(尽管 DirectX 在这方面肯定是头重脚轻),而是将渲染命令传送到显卡的通用方法。

        卡供应商是为特定卡提供实现(驱动程序)的供应商,在许多情况下,这与硬件非常相关,但您作为用户永远不需要关心一个用户运行的是 GeForce ABC 而另一个用户运行的是Radeon XYZ 因为确切的实现隐藏在高级 API 后面。如果不是这样,您将需要在您的游戏中为您想要支持的市场上的每张卡都有一个代码路径,这从第一天起就完全无法管理。这种方法的另一个重要优点是 Nvidia/ATI 可以发布一个更新、更高效的驱动程序版本,您无需付出任何努力即可自动受益。

        同样的原理也适用于声音、网络、鼠标、键盘……基本上是您计算机的任何组件。无论封装发生在硬件级别还是软件驱动程序中,在某些时候,所有设备细节都被隐藏起来,以便您可以将任何键盘视为键盘,而不是 Microsoft Ergonomic Media Explorer Deluxe Revision 2 .

        当您这样看时,很快就会发现,如果没有我们今天所知道的某种形式的封装/抽象计算机根本无法工作。这对你来说足够精彩吗?

        【讨论】:

          【解决方案4】:

          世界上几乎每个 Java、C# 和 C++ 代码库都具有信息隐藏功能:就像类的私有部分一样简单。

          外部世界看不到私有成员,因此开发人员可以更改它们而无需担心其余代码无法编译。

          【讨论】:

          • 我不知道我会说“无需担心其余代码无法编译”。您当然可以在仅更改私有成员时破坏编译。只要您不更改外部接口,好处就在于能够完全重写类的内部。这对于某些类型的优化非常有用。
          【解决方案5】:

          什么?你还不服气?

          显示相反的内容更容易。我们过去常常编写无法控制谁可以访问其实现细节的代码。这使得有时几乎不可能确定是什么代码修改了变量。

          此外,如果世界上的每一段代码都可能依赖于特定具体类的实现,那么您就无法真正抽象出一些东西。

          【讨论】:

            猜你喜欢
            • 2012-12-04
            • 1970-01-01
            • 2017-02-05
            • 2018-10-24
            • 1970-01-01
            • 2013-11-25
            • 2016-07-07
            • 1970-01-01
            • 2017-10-10
            相关资源
            最近更新 更多