面向对象其实不需要封装

Note: 这里的‘封装(Encapsulation)’指的是限制对象访问的语言特性,也被称为信息隐藏(information hiding)。翻译的初衷在于看看一些不同的想法,作者的思考在某个层次上是有道理的,但并是完全正确。总之这里有一个决策和角度的问题。

没有封装的OOP?

Python支持Object Oriented Programming, 却没有封装(encapsulation). 许多都对此不解,但讨论来讨论去,最终的结论是OO压根不需要封装。 Python里什么公有的,如果在成员名字前加两个下划线则表示不能由外部使用,也即非接口类的成员。但也有办法使用,当然风险自理。Python开发者称之为命名约定式的封装,而非强制封装。本质上,这并不是封装,也没有隐藏什么。原因何在?

用电脑做个比喻 

我可以随时打开我的电脑,升级一下,或者换个部件,这很容易做到。如果硬件厂商也开始使用封装,我们可能很难再打开机箱,如果要加个内存或换个什么,就只能送回厂家了。

如上封装限制了对实现细节的使用。但确实需要时,就只能自己动手了。硬件上并没有限制我把它打开,软件为什么要这样做?

使用抽象代替封装 

一个关于抽象(abstraction)的定义说到: ‘the act of considering something as a general quality or characteristic, apart from concrete realities, specific objects, or actual instances.’.
从编程上看,意思就是在实现之上提供一个接口,用户只需要知道接口层(即抽象层),而不用关心实现的细节。与封装的差异在于,如果用户想要去了解那些潜在的细节,仍然可以做得到。绝大多数硬件都是使用抽象代替封装,使用一个很少变化的接口,同时允许高级用户窥看细节。

当使用抽象代替封装时,用户可以清楚地看到接口,和使用封装的方式也没什么差别。我们鼓励用户使用开放的接口,但并不仅限于此。对于使用接口而言,抽象与封装的效果是一样的,只是前者允许访问背后的内容。这样使用者完全可以了解到他的行为可能带来的风险。

一个实例 

假设我用一个跨平台的GUI库来开发应用程序。跨平台的GUI库好用,在不同平台上也保持相同的接口,会省去不少麻烦。

假设Windows用户希望添加一个特别的功能。这个时候,你如果坚持封装,你会面临如下的问题::

  • 在原来的GUI库上实现一个新的库,这样就要包括其它的接口。
  • 联系厂商做特殊修改,这个可能性不大,即使可行,也未必来得及!
  • 放弃原先的库,在Windows上使用新的库。这个风险很高,成本也很高!

如果你转而使用抽象呢? 除了上面的选项外,你可以动到库里的细节实现,不过要考虑一下几个风险:

  • 有没有可以破坏其它行为。
  • 库的升级可能导致你的修改失败,所以每次升级时都要检查一下它的行为是否仍然正常。
  • 当然库的厂商可不一定愿意为你提供技术支持了。

就是说,使用抽象代替封装时,你一定要自行权衡利弊。我可不是鼓励大家使用那些细节的内容,只是在一些情况下,这可能是一个最佳方案。

How I do it 

在传统的OO语言,我将接口定义为public, 其它实现的细节内容我定义在protected中。四人帮曾经说: “因为继承会将父类的实现细节暴露给子类,所以通常称为‘继承破坏了封装’’”. 事实上,这正是我想要的效果。我的用户可以使用public接口,如果需要,他们可以子类化自己的类。

这招让我省了不少的事,我不用再纠结于private, protected或者public。我的座佑铭正是:Keep It Stupid Simple.

封装不是安全 

把数据隐藏或者保护起来不让用户接触到,通常讲是很有必要的。但如果是要讨论安全性,我认为通过封装来实现安全性是极为糟糕的。

结论 

依赖于细节实现绝不是什么好主意,所以只能使用类的公共接口。不过总有些意思不到情况让你需要使用一些内部细节,这个时候最好把类设计更加有用一些,让用记可以通过一些专业的方式来使用它。用户不是白痴,要假定他们都是专家,可以很合理的使用你的类来解决一些问题。如果他们要访问一些细节内容,自然有他们的理由,或许就是别无它法。所以,不要拿封装来对付他们。

原文地址.

转载请注明出处:http://blog.csdn.net/horkychen

时间: 2024-10-07 14:08:03

面向对象其实不需要封装的相关文章

php 面向对象详解_封装性

第七章(5)面向对象详解_封装性 封装性:就是将对象内部的属性或方法封装在自己的对象内部,在对象内部可以被使用或访问,但在对象的外部或者其它对象里不能使用封装的成员. 封装使用的关键字:private 封装的含义: 1.把对象的全部属性和全部方法结合在一起,形成一个不可分割的独立的单位(对象). 2.信息隐蔽,即尽可能的隐蔽内部细节,对外形成一个边界(或者说对外形成一个屏障),只保留有限的对外的接口,使它与外部发生关系.      第七章(6)面向对象详解_封装时所用的四个常用的方法 带"__&

重温面向对象的思想OOP——封装

面向对象的思想OOP--封装 对象的封装: 封装的目的:隐藏对象的内部细节,将对象进行黑箱操作.用户是不知道对象的内部细节的,同样的道理,用户也不知道你定义的方法. 说明:一个对象(类)的属性,这个属性必须一定是私有属性,用户一定不能直接获取得到属性,必须通过你定义的工程来操作数据(设置.得到), 标准格式:通过定义私有属性的Set方法和Get方法来分别设置.得到私有属性. package demo; public class Student { private double schoolCod

php学习笔记 php中面向对象三大特性之一[封装性]的应用

复制代码 代码如下: <?php /* * 封装性:面向对象三大特性之一 * * 1.就是把对象的成员(属性,方法)结合成一个独立的相同单位,并尽可能隐藏对象的内部细节 * 访问权限修饰符 public protected private * private:私有的,用这个关键字修饰的成员,只能在对象内部访问(只有用$this访问) * * 属性可以封装: * 只要一个变量,需要在多个方法使用,就将这个变量声明为成员属性,可以直接在这个对象中的所有方法中使用 * * 成员属性,相当于这个对象中的

php学习笔记 php中面向对象三大特性之一[封装性]的应用_php基础

复制代码 代码如下: <?php /* * 封装性:面向对象三大特性之一 * * 1.就是把对象的成员(属性,方法)结合成一个独立的相同单位,并尽可能隐藏对象的内部细节 * 访问权限修饰符 public protected private * private:私有的,用这个关键字修饰的成员,只能在对象内部访问(只有用$this访问) * * 属性可以封装: * 只要一个变量,需要在多个方法使用,就将这个变量声明为成员属性,可以直接在这个对象中的所有方法中使用 * * 成员属性,相当于这个对象中的

javascript 面向对象编程基础:封装_js面向对象

很长一段时间以来(这里本人要幸灾乐祸地说),js是"一种点缀的作用,完成很有限的功能,诸如表单验证之类,其语言本身也一直被当作过程化的语言使用,很难完成复杂的功能.".但是(这里本人要苦大仇深.痛心疾首地说),"而Ajax的出现使得复杂脚本成为必需的组成部分,这就对 JavaScript 程序设计提出了新的要求,很多Ajax应用开始利用JavaScript面向对象的性质进行开发,使逻辑更加清晰.事实上,JavaScript 提供了完善的机制来实现面向对象的开发思想."

面向对象的Javascript之三(封装和信息隐藏)_js面向对象

同时,我们知道在面向对象的高级语言中,创建包含私有成员的对象是最基本的特性之一,提供属性和方法对私有成员进行访问来隐藏内部的细节.虽然JS也是面向对象的,但没有内部机制可以直接表明一个成员是公有还是私有的.还是那句话,依靠JS的语言灵活性,我们可以创建公共.私有和特权成员,信息隐藏是我们要实现的目标,而封装是我们实现这个目标的方法.我们还是从一个示例来说明:创建一个类来存储图书数据,并实现可以在网页中显示这些数据. 1. 最简单的是完全暴露对象.使用构造函数创建一个类,其中所有的属性和方法在外部

Zebra_Database v2.3发布 面向对象MySQL数据库操作封装

Zebra_Database是一个高级,紧凑(只有一个文件),轻量级,面向对象的MySQL数据库操作封装.基于PHP的MySQL扩展.它提供http://www.aliyun.com/zixun/aggregation/11872.html">访问数据库的方法比PHP默认更加简单和直观.此外,它还提供调试控制台来查看SQL的执行情况. Zebra_Database it is an advanced, compact (one-file only), lightweight, object

Zebra_Database v2.2发布 面向对象MySQL数据库操作封装

Zebra_Database是一个高级,紧凑(只有一个文件),轻量级,面向对象的MySQL数据库操作封装.基于PHP的 MySQL扩展.它提供http://www.aliyun.com/zixun/aggregation/11872.html">访问数据库的方法比PHP默认更加简单和直观.此外,它还提供调试控制台来查看SQL的执行情况.提供了各种用于与 MySQL 数据库交互的直观方法,比 PHP 自带的更有趣. Zebra_Database it is an advanced, comp

php面向对象中构造 析构 封装性

构造方法与析构方法构造方法: 大多数类都有一种称为构造函数的特殊方法.当创建一个对象时,它将自动调用构造函数,也就是使用new这个关键字来实例化对象的时候自动调用构造方法. 构造函数的声明与其它操作的声明一样,只是其名称必须是__construct( ).这是PHP5中的变化,以前的版本中,构造函数的名称必须与类名相同,这种在PHP5中仍然可以用,但现在以经很少有人用了,这样做的好处是可以使构造函数独立于类名,当类名发生改变时不需要改相应的构造函数名称了.为了向下兼容,如果一个类中没有名为__c