初学COM,突然觉得,这真是个好东西,天啦,我终于开始学十几年前的微软技术了。。。
脑子里有太多东西,不知道从哪里记,就从封装开始吧。大学里学的是C(因为专业问题),但是我自学的是C++,我当时以为C++是C的扩充,就像C2。0一样。说C++是面向对象,C是面向过程,这一年级的学生都能脱口而出,但到底为什么要面向对象,为什么数据结构+算法的模型不能胜任现在的大型软件开发?面向对象把它变成了
对象=数据结构+算法
程序=对象1+对象2+。。。
为什么不能胜任?如果你做为开发者,然后去听一下那些完全不懂计算机的客户老板对项目的不断改变的需求,甚至到无耻的地步的时候,你就会彻底抛弃你对C编程的自信。
我没有说C不好,在很多方面,C比C++好,C++就好像迈了一步,但是还是有很多问题需要解决,一条脚还在原地。
对象就是对数据结构和算法的封装的实例。把数据和方法绑在一起,就叫一个类,类一实例化,就是对象。从代码上看,就像这样
class A
{
int data;
public:
void foo();
};
Thinking in C++一书里前面部分专门讲,这样做的来源,因为很早C程序员就是这样想的,只是形式上没有这样做,比如
struct A
{
int data;
};
void foo(struct A*);
这有什么区别?除了好看些,名字可以有更好的一些作用约束之外,似乎没有任何进步啊。同样,C++的编译器也正是这样做的,将上面的class A进行sizeof(A)运算,结果是4,那个成员函数被编译器移出了类,非常巧妙地欺骗了天真的C++初学者。同时,编译器在调用成员函数的时候,将this指针偷偷换进去,实质上这和C的代码一模一样,而一年级的学生可能会因为自己学了C++,能写出一些用类描述的程序,而觉得非常了不起。
你看不下去了,我这里没有干系到类的继承,你要说多态啊,没有多态哪里是面向对象?很多人这样说。可不可以先不想后面的事情,为什么要用类,为什么要用面向对象,都不明不白,就接着讨论,是不是有点像站在空中说话一样,一点不踏实。
我要说的封装,应该是,接口和实现的分开。接口是功能的描述,是交给用户的按钮,实现是设计人员的事情。非常不巧,其实面向对象和数据结构和算法八杆子打不着,根本没关系,而数据结构和算法都是实现的范畴。于是关系是变成了:
对象=接口+实现
用户的角度,对象=接口集,实现被设计人员封闭
实现=数据结构+算法+等等一切软件方法或手段
然后再问为什么要封装,比如,为什么你家的电视要一个外壳,而不把里面的电子电路板露在外面,或者外壳用一个玻璃外壳呢?没必要,用户根本看不懂。还有一个原因,让用户的重点放在接口上,对他有好处,同样让设计者的重点放在实现上也是一种责任。你打开一个新的软件,运行时有一个窗口,右上角有一个叉的按钮,你不用翻说明书,也会知道,那个按钮一按程序就会退出,天啦,你真聪明。同样的事情,你家的电视从老的CRT换成了液晶宽屏,但是遥控器上的按钮对你一点也不陌生,你同样可以使用它!
如何封装?《Effective C++》里提到过,2种方法,1是所谓的ptimpl手法,即point to implementation,引出一个实现类,将实现类在用户头文件中进行申明而不定义,在实现文件中定义,接口类中拥有一个指向实现类的指针;2是专门设计接口基类,利用了虚函数和继承。
源代码的封装对有些场合不合适,如果你在你的软件中使用了新的实现类,那就必须对用户有个过分的要求,要他的机器上安装了编译环境,将你的源代码非常公开的发给他,然后他重头重新编译连接一遍,完成软件升级,或者你将先重头编译一遍,然后整个传给用户,就像重新安装一个一样(这点或许在支持开源软件的人看来,是多么容易,和多么应该做的事!但开源软件,只有让精英用,才有发展的可能,而大多数的用户,对计算机的了解,可能接近白痴)。COM做的封装就是二进制封装,二进制重用,让大型软件分成很多个组件,组件可以动态的,在运行时,装入进程,然后使用。
这种方法会使得接口的设计的重要性突出出来,软件过程里到底什么最重要?算法还是数学,还是设计?
好啦,结束啦,这只是我的笔记。从明天起,认真写好一个C++程序吧!
评论