谈系统设计之面向对象设计方法
误解
刚开始出道,从事C++编程,也了解了面向对象设计方法。
但是,那时以为只有像C++、JAVA这样的开发语言,才有面向对象这种设计方法。
无处不面向对象
后来,到了HW公司后,从事内核开发,Linux 内核文件系统的了解,才发觉 “面向对象”无处不在。
Linux 内核设计也无处不面向对象,比如设备驱动模型、文件系统等都是采用面向对象的设计精髓。
举个例子,Linux 的文件系统:
图一:FILE
在Linux 中对每个文件抽象一个结构体File,该结构体含有一个成员文件的操作函数集合。
用面向对象的角度来说,是一个类File,一个类的FileOperationInterface,这两个类再不同的文件系统类型中,是跟不同的
具体实现组合起来,满足不同的文件系统的操作。
从而Linux 可以很方便地支持多种文件系统,只要各种文件系统根据接口契约来实现,就可以。
因此,面向对象设计的精髓:
1)抽象,尤其是对变化的地方,进行抽象,不同的文件系统可能根据其不同的空间管理、格式,读、写操作可能不一样,
因此通过抽象的方式抽象一个文件操作函数集合。
2)针对接口编程,接口是一种契约,大家根据这种契约进行实现,就可以达到兼容、扩展、替换。
3)封装,将变化的地方封装成一些接口(类),防止不稳定的因素在整个系统中扩散。
4)组合,就像一个File 结构体 和不同的File 操作实现组合,形成了不同文件系统的特有操作。
再举一个Linux 内核的CACHE,在Linux 内核中,Cache 支持一下的类型:
1)普通文件数据的缓存页面(page)
2)目录项的缓存页面
3)块设备文件的块数据缓存页面
4)进程用户态数据的缓存页面
5)特殊文件的缓存页面,比如进程间通信的页面SHM。
所有的缓存页面是通过页高速缓存来处理,打个简单的比方是采用一个通用的线程来对这些不同类型的缓存进行预读、刷盘、同步、删除等操作。
通用也是利用面向对象的方法来处理:
图二:CACHE
设计模式
借此也谈下对设计模式的一些看法,早期我学设计模式是4年前,那时没有什么工作经验,因此实现任务时候,
总是想拿设计模式来套,结果是每次都会写很多多余的代码,或者每次编码总是写块头很大的代码。
其实,这也是早期没有领会到本质,先生搬硬套,固化固化。
其实设计模式的本质是:
1)抽象
2)封装、继承
3)优先采用组合
关键是对问题的理解,从而发现适当的模式。
也就是说你面临的问题是什么,有不稳定的因素吗?即存在变化点。
如果这是存在变化点,你就要去抽象、封装。然后,你要考虑是耦合问题,以及考虑继承是否会导致膨胀。
这时你的策略就是优先采用组合。
架构模式
架构这个问题太深了,但是架构常见的解决方法就是:
1)分层
2)抽象