游戏开发论坛

 找回密码
 立即注册
搜索
查看: 59461|回复: 50

封装的意义和喻义

[复制链接]

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2007-1-15 13:39:00 | 显示全部楼层 |阅读模式
我一直在不遗余力得推荐大家去看<<Exceptional C++ Style>>的16、17、18章
原因是这三章是我目前为止看到众多文章中阐述私有、封装、多态、继承表达最清楚的了
需要反复咀嚼
今天又看一遍
摘录其中几句关键的话与大家分享

1. 封装意味着什么?
    en-cap-su-late:  用囊状物包围、包装或者保护

2. 一个良好的类接口能够隐藏其所性类的内部实现,并向外界提供一个与类的内部实现分离和区别开来的"interface"
    细菌细胞膜外表面的意义在于与外界进行感知、接触以及发生交互作用

3. 一个良好的类接口设计必须是完整的,同时又不能暴露类的任何内部实现
  如果一个细菌的细胞膜不是封闭的,那么这种细菌肯定活不长;其内部的有机组织会迅速溢出,它也肯定会死亡

4. 一个良好的类接口会保护类的内部实现,以免它们遭受未经授权的访问和操作
  杀灭细菌(和人类)的主要手段是制造能够破坏细胞膜的东西. 从微观层面来说,这包括化学制品、酶或者能够适当制造破孔的有机生物体(或许最终是纳米机器人). 而从宏观层面来说,刀和枪都是人类长久以来热衷的武器

5. 封装是面向对象编程的核心概念

6. 所谓面向对象,通常定义为:  数据以及操作这些数据的函数的组合,补充 - 通过由一组函数构成的接口将调用代码与内部数据隔离开来(由接口来负责操纵内部数据). 此观念强调了两点,一点是低耦合度,另一点是被组合起来的函数构成了一个起保护作用的接口

7. 简单的说,面向对象就是关于将接口和实现分享的方法学,只不过这种分离必须能够改善高内聚性和低耦合度

8. 除了struct的情况,数据成员永远都应当为私有的

9. 公用数据违反了封装原则,因为它允许调用代码直接操纵对象的内部信息,这意味着对调用代码的高度信任

10.在现实当中,很少人需要直接去操纵对象的内部实现,举个例子,很少有人需要直接操纵我的胃,因为那样他们可能很容易一不小心就干错事. 至多他们只会通过我的公用接口去间接地操纵我的内部,这种做法的好处是他们在进行操作之前必须首先让我知道并得到我的认可才行,例如递给我一瓶标有"喝掉我"字样的液体,那么我可以决定是喝了它,还是用它来洗头或洗车,根据自己的感觉和判断. 当然,有些人的确有资格直接操作我的"内部",例如外科医生,只不过即使如此:  a. 这种情况也很少见  b. 我至少能够选择是否愿意接受手术 c. 我至少能够选择我高度信任的医生.以上是合法范围,否则就是强暴了,像reinterpret_cast那么粗鲁,是不会给人以好印象,也不会带来良好的结果


窃以为以上9点皆为前戏,在第10点才道出了高潮,我略微在最后加入了一点我的新的见解,希望大家看了之后会明白,会HIGH~

http://www.cnblogs.com/oiramario/archive/2007/01/15/620778.html

15

主题

368

帖子

406

积分

中级会员

Rank: 3Rank: 3

积分
406
发表于 2007-1-16 00:22:00 | 显示全部楼层

Re:封装的意义和喻义

前戏,高潮

顶一下。

5

主题

217

帖子

222

积分

中级会员

Rank: 3Rank: 3

积分
222
发表于 2007-1-17 15:56:00 | 显示全部楼层

Re:封装的意义和喻义

从《effective c++》《more effective c++》到 《Exceptional c++》、《more Exceptional C++》,每看一条手心就直冒冷汗…

0

主题

7

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2007-1-17 18:09:00 | 显示全部楼层

Re:封装的意义和喻义

high了……

16

主题

266

帖子

296

积分

中级会员

Rank: 3Rank: 3

积分
296
发表于 2007-1-18 09:26:00 | 显示全部楼层

Re:封装的意义和喻义

谢谢楼主分享

13

主题

27

帖子

33

积分

注册会员

Rank: 2

积分
33
发表于 2007-1-18 12:48:00 | 显示全部楼层

Re:封装的意义和喻义

顶一下。。。。

5

主题

217

帖子

222

积分

中级会员

Rank: 3Rank: 3

积分
222
发表于 2007-1-18 15:59:00 | 显示全部楼层

Re:封装的意义和喻义

不知道 马肝 兄对 书里面的 “接口非虚,虚函数为私有” 怎么理解
基于组件的重用如果没有纯虚接口也不会有问题么?看的不是很明白,请教之

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2007-1-19 09:40:00 | 显示全部楼层

Re:封装的意义和喻义

有很多书是好书,理论也是好理论。
但是,如文中引述的“良好的类接口”以及“低耦合度”,相信刚会写代码的新手连看十本这样的书也无法在实际应用中达标,而等成为经验丰富的高手后,这两点早就成为设计的基本要素,再翻看本书的这一段似乎也没什么意义了。
所以要买书学习,关键的问题在于应该懂得什么时候该看什么样的书。

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
 楼主| 发表于 2007-1-19 13:20:00 | 显示全部楼层

Re:封装的意义和喻义

2 MathSlope:
从根本上来说,首先需要把一般概念中的public成员函数上升到interface的层次,这个感觉不是简单的define x y,而是typedef y x,而interface既然是public的,是提供给外部的操作接口,那么它的形态就必须是stable的,也就是说名字不能变,返回值和参数一个都不能变,而对于直接操作public/protected的成员变量,这就是高耦合性,这里把protected也算在内是因为未来谁会操作protected里的东西是不可知的,这同样意味着存在安全性的问题;同样如果直接操作public/protected的虚函数,因为virtual是多态的,其设计目的是针对其派生类的实现行为,表现是不稳定的,当需求发现变化(比如在函数实际调用前要增加一段检查),这时它就无法实现而最后还是必须退回使用一个non-virtual public的接口如Render,其中会调用一个virtual的private成员函数如DoRender来实现,请注意前面两者的称呼一个叫接口另一个叫成员函数. 当然,书中也提到是&quot;尽量&quot;而不是&quot;必须&quot;,这也是C++的特点,你几乎不用受到什么限制,没有谁说你非要这样做,不这样就不行.

所谓设计,不是简单的把一堆接口都public出来就OK了;所谓封装,也同样不是简单的把一堆变量码在一起就完事了. 当大型项目时,当开发人员五湖四海无法集中讨论和修改时,当需求有可能发生变化时,当代码量大到不能轻易修改、增加或删除某一个函数的参数时,上述的做法可以保证你的设计和代码能够有足够的强壮性来面对未来发生的变化.

建议你继续仔细得把18章看完

2 系统崩溃:
你说的很对,对于新手,上述概念是枯燥、乏味、不方便和无法理解的,所以书中也提到过,人只有经历过痛苦的磨难才会意识到需要寻找一个更有效的方法. 书籍和讨论的意义在于,过来人看了会会心一笑;没来过或是正在来的人看了应该警惕不要重复前人已经犯过的错误,连圣斗士都说同样的招式你不需要对着我使两次,而人类的都是先从模仿开始慢慢在过程中成长,像是讲话和行为,从一开始的简单clone,慢慢的才会形成个人的风格和意识.


最后,我认为C++注重的是thinking,这是大局观、宏观,而具体的technique属于微操、微观,以星际为例,虽然微操好的人可以在某一两次局部战争中获得优势,但是从整体上来看可能早已是四面楚歌. 所以一个好的星际选手应该同时具备上述两点! :)

5

主题

217

帖子

222

积分

中级会员

Rank: 3Rank: 3

积分
222
发表于 2007-1-22 12:00:00 | 显示全部楼层

Re: 封装的意义和喻义

马肝:
我的意思不是说基类封装应不应该用虚函数,而是说比如我要做一个库(比如dll),这时我想对外部给出的是一个只能功能接口的抽象类,如
struct ICommand
{
public :
virtual uint Do(void) = 0 ;
virtual uint16 UnDo(void) = 0 ;
virutal uint16 ReDo(void) = 0 ;
};
这种形式的接口。我是想问:对于这种类型的接口是否也应该封装成
class ICommand
{
public:
    uint Do(void)  ;
   uint16 UnDo(void)  ;
   uint16 ReDo(void)  ;
protected:
    virtual uint ImpDo(void) = 0 ;
    virtual uint16 ImpUnDo(void) = 0 ;
    virutal uint16 ImpReDo(void) = 0 ;
};
那种非虚的封装我感觉对类库如MFC\NET FCL等我觉得是很多好处,但对于基于组件的重用性封装,我没发现有什么好处。比如我只让客户使用我的DLL中的ICOMMAND接口而不是去继承它 。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 23:01

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表