文章学习于
http://blog.csdn.net/breaksoftware/article/details/8439975
感谢该博主。
如果要学习WMI的技术原理,直接看他的一系列文章就可以了。
本文只是从构架层面学习原作者的思路。
获取系统信息的类图如下。CWMI,CSynQuery,CSynQueryData。
原作者,从三层对这次些查询操作的过程进行抽象和分类,典型的面向对象思维。
第一层:
CWMI封装了环境的初始化,连接WMI,设置权限等,每次查询需要的通用操作。
然后留下了一个Excute的纯虚函数,以便子类对不同的对象进行扩展。
在ExcuteFun函数中,顺序列出查询的步骤,留下Excute给子类重写。有点模版方式的味道。
第二层:
CSynQuery继承于CWM并实现Excute方法,利用IWbemServices的指针,进行查询。
该类需要名字空间与查询语句,需要在构造函数中提供。
在Excute中查询,并对结果进行遍历,每次遍历的一个对象交由DealWithIWbemClassObject处理。
DealWithIWbemClassObject对该对象进行处理。
枚举该对象的所有数据项。每得到一个数项,交于DealWithSingleItem处理。
在CSynQuery中DealWithSingleItem是纯虚函数。需要子类实现。就是说留有怎么去处理这个数据项的扩展。
在这个层次中,仅关心用IWbemServices查询数据对象。
第三层:
CSynQueryData继承于CSynQuery,实现了DealWithSingleItem,对单个数据项的处理。
这里的处理是直接根据类型进行打印。当然也可以有别的实现。
在这里对数据类型进行了判断,进行选择打印的方式。
总结:
通过各个层次上的抽象,将整个复杂的过程,划分多个步骤,放到不同层次中。
降低了程序员关注的复杂度。
每一层,只关于一部要处理的事。关注的东西少。
CWMI只处理初始化,提供环境。不用关心怎么查,查到之后怎么办。
CSynQuery只做查询,把查询的结果留给子类处理。用关心环境的建立与数据结果的处理。
CSynQueryData就单独对数据结果进行处理,可以进行类型的判断输出等。
内聚性上很强,每一个子程序只用一件单一的事。
易于扩展,只要复写继承上面的类,即可完成特定的需要。
与之有一篇文章,也是WMI获取信息的,不过他是面向过程的处理思维。
见文章:http://blog.csdn.net/jhqin/article/details/5548656
作者也写行非常好,我只是拿这个面向过程与面向对像的比较来做个学习案例。
暂且前面的称A,后面的称B
扩展性上,B方式,若需要再增加一个查询,必须修改szWQLQuery的数组,而且要整体修改处理逻辑。
A方式,若只需要输出,用不同的查询语句构造CSynQueryData就可以,若要换一种输出方式,只需要继承CSynQuery,重写DealWithSingleItem。并不要改动别的代码。
这样出错的可能性降低了。测试方面,B方式可能要回归测一下以之前的查询有没问题(因为该函数逻辑修改了),但A方式,只需要测试新类就可以了。原有的查询没有修改,不用测试。
在异常处理上,A方式,用的智能指针,不用担心资源释放问题。B方式,处理函数调用失败,都要去调用释放资源。B方式程序员关注的细节多了,精力就可能被分散。
附MSDN中提供的查询对象
http://msdn.microsoft.com/en-us/library/aa394388%28v=vs.85%29.aspx