haoxiaobo

从C到C++又到.net, 有一些心得, 和大家交流下...
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

用派生类的方法实现设备无关性

Posted on 2005-01-11 16:16  HAL9000  阅读(839)  评论(0编辑  收藏  举报

    你的程序需要操纵一类设备, 设备有多种,  需要不同的程序来驱动, 但是大概都是同样的功能.
    我遇到的东西是语音卡,  有各种不同的语音卡, 如dialogic, tw等, 甚至还有我自己写来用于测试的一个demo假设备.不同的设备需要有不同的方式来放音, 录音, 拨号等等. 但是都是录音, 放音, 拨号, 收号. 你的程序需要支持这些不同的设备, 而且必须在用户那里选择硬件类型. 怎么办?

    我这里采用了一个办法, 就是抽象出一个虚设备基类来, 定义纯虚方法录放音什么的功能, 然后不同的设备都从这里个基类里派生出子类做为驱动程序, 根据客户的要求创建不同的子类对象来, 重载这些统一功能的各由实现, 而在你的主应用程序里实现时, 则只采用基类的抽象方法.

    如我就定义了一个基类叫: VCtiDriver, 里面都是一些abstract方法, 还有的就是一些事件的定义, 如:设备打开了呀! 关闭了呀! 等等. 这里不写了呀!

    然后其他实际操作不同种设备的子类都从这个类里派生出来, 如drvDialogic, drvDemo之类的, 在各自的实现里override基类里的abstract方法. 这些代码也不用多说了.

    关键点在以下两点:
    一, 用户选择时, 如何得到所有可以用的设备类型, 也就是从VCtiDriver里派生的全部子类.
    二, 用户选择了, 如何从这个已经选择的内容里建立一个实际的对象.

    下面是我用的方法:
    一, 用户选择时, 如何得到所有可以用的设备类型, 也就是从VCtiDriver里派生的全部子类. 
    下面就是办法.注意:this是一个form, cmbDrivers是一个combox, 这段代码我放在form_load里,init里也可以.
    在combox里放的是驱动程序的类名和程序集名, 必须要用: 全类名 + "," + 程序集的格式才好. 

得到一个类的所有派生的子类:    
            Type typeVCtiDriver = typeof(VCtiDriver);
            Assembly asm 
=
 typeVCtiDriver.Module.Assembly;
            Module [] arMds 
=
 asm.GetModules();
            
foreach(Module md in
 arMds)
            
{
                Type [] arTypes 
=
 md.GetTypes();
                
foreach(Type t in
 arTypes)
                
{
                    
if
 (t.IsSubclassOf(typeVCtiDriver))
                    
{
                        
this.cmbDrivers.Items.Add(t.FullName + "," +
 t.Assembly.FullName);
                    }

                }

            }


用户选择了一个驱动程序项之后, 你可以把那个类名+","+程序集名的字串保存下来, 下次就别让用户再选了, 直接默认比较友好, 这是后话. 

    二, 用户选择了一个设备, 如何从这个已经选择的内容里建立一个实际的对象.
    选择完成之后, 这还只是一个字符串, 需要把这个串变得一个类的对象.  更简单, 下面是代码.

从类名字符串创建该类的实例:
            Type typeDrv = Type.GetType(this.cmbDrivers.SelectedItem, falsetrue);
            
if (typeDrv == null
)
            
{
                MessageBox.Show(
this"没有找到指定的驱动程序, 请用选项菜单重新设置驱动程序类型."
);
                
return
;
            }


            
// 用设备驱动程序名来新建程序类。无论什么子类, 都抽象为基类.

            VCtiDriver drv = (VCtiDriver) Activator.CreateInstance(typeDrv);

好了,  拿drv来用吧, 这个对象就是你的实际的子类对象.

打完收功, 你可以再美化一下, 把类名什么对用户HIDE起来, 想办法用中文的说明来显示之类的都不是问题.