`
yingyingol
  • 浏览: 762010 次
文章分类
社区版块
存档分类
最新评论

封装与信息的隐藏

 
阅读更多

封装与信息的隐藏




显示了肆虐一时的SARS病毒结构图。可以看出,病毒可以分成三个层次:一层坚硬的壳层,壳层外呈触角状的蛋白体,以及壳层内部的遗传物质。显然这种构造使得SARS病毒得以隐藏和保护自身内部结构,这是病毒经过漫长时间的演化形成的有效生存机制。
无独有偶,面向对象的软件设计中,对象也可以分成三层,一层由各个方法构成的壳层,暴露在壳层外的各个接口,以及受到保护的内部属性,参见图4.2。


图4.1、SARS病毒模型。(www.who.org) 图4.2、对象由属性和方法组成,对象向外界提供接口以供操作对象内部属性和触发对象的行为。
对象的这种结构,使得封装(Encapsulation)与信息隐藏(Information Hiding)变得可能。封装和信息隐藏常常被混为一谈,但它们并不是一回事。
4.1 封装
到底什么是封装呢?让我们还是从四十年前谈起吧。
如本书在第1章中介绍的,世界上第一个具备面向对象特征的语言是Simula。是Simlua第一次引入了真正意义上的封装。
在六十年代,模块化编程是基本的设计手段,模块化也是Simula的基本设计思想,只是Simula的模块化非常有特色:模块的设计不是建立在过程之上的,而是建立在真实世界中的物体基础之上的。
每一个真实的物体都有一些需要模型化的行为,每一个真实的物体都有一些关于其状态的信息。这些物体相互作用,形成了Simula需要描述的模拟系统。Simula的设计师决定以最为接近真实物体的办法进行模拟系统的设计,这样一来,按照真实物体的组织来组织模块,就是顺理成章的了。
将数据和作用于数据之上的操作绑在一起形成模块,这就是封装。
一场对象技术的革命就是这样开始的。这场革命开始于封装。
一个例子:棋盘上的点
对象是对真实世界中的物体的抽象化,但对象不是照搬真实世界中物体。对象技术中的建模不是把真实世界照搬到软件系统中,对象技术首先要将真实世界理想化、简单化、抽象化,然后把这个改变了的影像搬进软件系统中。
读者一定建国围棋棋子和棋盘吧,本节就考察一下如何为围棋棋盘上的点建模。

图4.1、围棋的一间跳、点三三。 图4.2、Point类的类图
下面的Point类描述在棋盘上的一个点,它带有两条数据,分别代表横纵坐标。这个类可以用UML描述,参见图4.2。
代码清单4.1、Point类描述棋盘上的点
public class Point {
public single x;
public single y;
}
与点相联系的操作有下面这些:
 移动(move):将这个点对象移动到另一个位置,就好比把一个围棋子从棋盘上的一个点移动到另一个点。
 计算距离(distance):与这个点与另一个点的距离。围棋手需要计算的比这个要复杂得多。
要实现这些方法,需要一个新的工具类,不妨称作PointUtil如下 :
代码清单4.2、操作点的工具类
public class PointUtil {
public double distance(Point p1, Point p2){
return Math.sqrt( (p1.x - p2.x) *(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
public void move(Point p, double x, double y){
p.x = x;
p.y = y;
}
}
如果要移动一个点,就把这个点传入PointUtil对象的move方法,同时需要传入的还有新的坐标。这个PointUtil对象会把Point对象移动到新的坐标。
如果要计算一个点到另一个点的距离,就需要把两个点对象传入到PointUtil对象的distance方法中,这个方法会返还你想知道的距离。譬如下面的代码就设定了两个点,并计算出他们的距离:
代码清单4.3、如何计算两个点之间的距离。
public static void main(String[] args){
Point p1 = new Point();
Point p2 = new Point();

p1.x = 10.0F;
p1.y = 20.0F;

p2.x = 100.0F;
p2.y = 200.0F;

PointUtil putil = new PointUtil();
System.out.println(putil.distance(p1, p2));
}
有两种设计师往往会给出类似于上面的这种设计。
熟悉过程性设计概念,初学对象技术的设计者常常会给出类似上面的设计。这种对责任的划分方法明显地带有过程式设计的痕迹,因为虽然设计中也使用了类,给人的感觉是如果Java允许把方法放到类外边去,设计者可能会更高兴。Java语言强制设计师使用类,但是使用了类,并不能保证一个设计就真正体现了对象思想的。
另一类设计者试图原封不动地在软件系统中重现真实世界,他们会认为这是一个好的设计:这难道不是对现实世界的真实描述吗?在现实世界中,围棋子会自己走路吗?难道不是外力移动棋子?棋子难道知道计算距离吗?难道不是一个计算器什么的负责计算距离吗?
不错,在现实世界中是这样的。但是这个现实世界不是一个理想化的,而是一个蹩脚的现实世界,你不想把这样的现实世界原封不动地搬进软件模型中。
在一个理想化的世界中,围棋子难道不应当自己会移动吗?外界只需要传送一个消息给棋子,棋子就自动到位。这虽然是想象中的事情,但是并非距离现实很远,只需要借助于一定的电子科技,完全可以在改进的棋子和棋盘上实现这一点。难道你不想把这个聪明的棋子和棋盘当作原型加以引进吗?
如何划分责任是面向对象的设计与过程性设计的基本区别。如果一个对象包含了某项操作所需的全部数据的话,那么这项操作就应当属于这个对象,而不是属于另一个不能提供所需数据的对象。上面所讨论的move方法需要改变的是Point对象的两个属性:x和y,而这两个属性就在Point对象内,为什么不把move方法交给Point对象呢?
基于同样的道理,计算一个点与另一个点的距离,需要两个点的坐标,而坐标本就是Point对象的属性,为什么不把这项计算任务交给Point对象呢?当然,这就意味着PointUtil类根本就没有用处,可以取消。

分享到:
评论

相关推荐

    【IOS苹果免签分发】苹果IOS绿标免签封装app隐藏顶部网址ios14不显示顶部网址跳转设置.rar

    标题提到的"【IOS苹果免签分发】苹果IOS绿标免签封装app隐藏顶部网址ios14不显示顶部网址跳转设置",就是一种针对iOS系统的免签解决方案,特别强调了在iOS 14系统下隐藏顶部网址和防止跳转的功能。 免签封装主要是...

    简单封装的轮播图插件,包含自动无限循环播放,标记点显示与隐藏,设置间隔时长,配置简单,支持移动端

    本文将详细介绍一个基于原生JavaScript封装的简单轮播图插件,它具备自动无限循环播放、标记点显示与隐藏以及设置间隔时长等功能,同时优化了移动端的兼容性和用户体验。 首先,我们来理解“封装”的概念。在编程中...

    仿25ge封装的APP封装源码-可以封装安卓和IOS.zip

    - **去除顶部网址和绿标签名**:在APK封装过程中,可以修改应用的界面元素,例如隐藏顶部的网址显示,以提供更沉浸式的用户体验。绿标签名通常指的是安全证书信息,去除它可能涉及到安全风险,但有时为了定制化界面...

    仿25ge封装的APP封装源码-可以封装安卓和IOS

    在描述中提到的"去除顶部网址,绿标签名"等功能,通常是指自定义Android应用启动器或者主题,可以改变应用的显示样式,比如隐藏应用的原始URL,以提供更加定制化的用户体验。 转向iOS平台,iOS应用的封装主要是通过...

    。net封装与拆封

    总的来说,`.NET封装与拆封`是面向对象编程中的核心概念,它在.NET框架下广泛应用于类的设计和网络通信。通过合理地封装和拆封,我们可以构建更加健壮、安全和易于维护的系统。在实际应用中,如游戏启动器这样的软件...

    javascript设计模式 封装和信息隐藏(上).docx

    JavaScript设计模式中的封装和信息隐藏是面向对象编程中的核心概念,它们旨在保护数据免受不必要的外部访问和修改,从而提高代码的稳定性和可维护性。虽然JavaScript不是一种典型的面向对象语言,但通过一些技巧和...

    【IOS苹果免签分发】苹果IOS绿标免签封装app.rar

    标题“【IOS苹果免签分发】苹果IOS绿标免签封装app.rar”暗示了我们讨论的是一个关于iOS应用免签分发的技术,特别是与苹果绿标(即企业证书签名)相关的技术。 苹果的绿标免签,是通过企业级开发者账号来对应用进行...

    VUE3二次封装vuetify3的snackbar

    Snackbar 在 Material Design 中是一个用于展示短暂通知信息的组件,通常在屏幕底部短暂出现,不影响用户的主要操作。 本项目是针对 Vuetify3 进行的二次封装,以适应 Vue3 的新特性和 TypeScript 类型支持。在 Vue...

    课程设计的封装部分截图

    - **信息隐蔽**:隐藏内部实现细节,使得用户不必了解对象内部的具体工作方式,只需知道如何使用其提供的接口即可。 - **版本控制**:如果对象的内部实现改变,只要对外接口保持不变,不影响其他部分的代码。 4. ...

    java版信息隐藏软件

    Java版信息隐藏软件是一种利用Java编程语言开发的工具,它主要功能是实现信息的隐藏,以保护敏感数据的安全。在信息安全领域,信息隐藏是一种技术,通过将信息嵌入到其他载体(如图像、音频或文本文件)中,使得非...

    json_value20190219.zip_RapidJson 简单封装_json封装_rapidjson_rapidjson

    6. **内存管理**:封装可能隐藏了RapidJson的内存管理细节,使得开发者不用直接处理动态内存分配和释放。 7. **单一头文件**:根据描述,这个封装仅依赖一个头文件,这意味着用户可以轻松地将它包含到自己的项目中...

    腾讯im对接简易封装腾讯im对接简易封装

    封装的目标是将腾讯IM的底层细节隐藏,提供一套更符合自己应用需求的API。例如,可以创建一个`ImManager`类,统一处理登录、发送消息、创建群组等操作。这样,其他开发者只需要关注业务逻辑,而无需关心底层实现的...

    POI操作Excel的封装

    约定通常是在封装过程中设定的一系列规则,这些规则定义了如何将Excel文件与Java对象相互映射。例如,可以约定第一行是表头,对应Java对象的字段;数据从第二行开始,每行数据映射到一个对象实例。这样,读取Excel...

    Okhttod 的简单的二次封装

    这种封装通常会创建一个更高级别的HTTP客户端类,例如`OkHttpManager`,以提供更简洁、直观的调用方式,同时隐藏底层复杂的配置和操作。 在提供的压缩包中,"okhttpmanager"很可能包含了这个二次封装的代码。这个`...

    c++ socket类封装(udp/tcp)

    总结,C++中的socket类封装对于新手来说是一个很好的起点,它提供了易于理解和使用的接口,隐藏了复杂的网络编程细节。无论是TCP还是UDP,理解并实现这样的封装都有助于提升程序员在网络编程领域的技能。通过学习和...

    AD封装库 常用音视频类封装

    音视频类封装就是将底层的音视频处理细节隐藏起来,通过提供简洁的API接口,让开发者能够更容易地进行音视频的编码、解码、播放、录制等一系列操作。 该封装库包含了各种常用的音视频类,这意味着它可能包括了以下...

    C++ 封装的MYSQL 类

    在面向对象编程(OOP)中,封装是核心原则之一,它隐藏了数据和功能的具体实现细节,仅对外提供接口。在C++中,我们可以通过定义类并提供公共成员函数来实现封装。对于MySQL,封装类可能包括连接数据库、执行查询、...

    超强的AFNetWorking封装框架

    - 对AFNetworking进行封装的主要目的是简化使用,隐藏复杂性,提高代码可读性和可维护性。 - 可以创建一个网络服务类,统一管理所有网络请求,包括请求的创建、发送、错误处理和结果返回。 - 封装还可以实现请求...

    基于Visionpro的二次开发,机器视觉相关基于康耐视工具Pma的封装与定义

    除此之外,我们可以将Pma封装与定义作为一个基础,扩展到更高级的检测方案。例如,结合深度学习技术,训练自己的模型来识别更复杂的图案;或者使用康耐视的其他工具,如Blob分析、形状匹配等,进行多步骤的图像分析...

    封装、继承、多态.docx

    封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据细节,只保留一些接口使其与外界发生联系。 封装的好处: 1. ...

Global site tag (gtag.js) - Google Analytics