期刊专题 | 加入收藏 | 设为首页 12年实力经营,12年信誉保证!论文发表行业第一!就在400期刊网!

全国免费客服电话:
当前位置:首页 > 免费论文 > 经济论文 > 国内经济 >

泛型技术消除观察者模式类型依赖探微

1设计与实现

为了提高软件的开发效率与软件的复用性,在系统的开发过程中常会引入第三方库或复用既有代码,而这也符合面向对象技术不重造“轮子”的思想[6-7]。对于这些既有代码,在复用其提供的功能时,常常还会加以调整以满足特定需要。在用户界面系统开发过程中,观察者模式适用场景非常广泛,而既有代码可能并不满足观察者模式各个类之间的协定。在观察者模式的传统实现中,虽然目标并不需要知晓所有观察者的类型,但所有观察者对象却必须保证实现观察者接口,即观察者必须处在同一继承体系下。为了让现有代码可以复用观察者模式。一个解决方案是引入多继承,即在继承已有代码的基础之上,同时实现观察者接口。但多继承并不被所有面向对象语言所支持,而且使用多继承也会增加开发者的负担,在使用既有代码的同时,每个观察者对象还需要继承一个不提供任何功能,只为实现约定的一个“桩”类。针对这一情况,有必要使用新的方法来消除观察者模式类型依赖。泛型技术本质上是将类型也作为一种参数传递。在强类型语言中,会在编译期对参数或数据进行类型检查,这就限定了在使用方法或数据时必须为其指定具体类型,造成的一个后果就是相同的算法必须针对每个类型定义一个版本,对于某些语言,如C++,可以通过宏来解决这一问题,但引入宏的一个负作用就是失去了类型检查的功能,导致类型错误只能在运行时发现。泛型技术解决了这一问题。在STL中,可以定义一个泛型数组vector<T>,在使用vector时可以指定T的类型,编译器会执行强类型检测,这样在定义算法或数据时就无需指定具体类型,只需在使用时指定一个类型。在面向对象语言如C++和Java中,使用泛型技术实现了各种算法和容器。这种做法虽然有效地降低了类型依赖,但在使用这些容器或算法之前,仍必须指定具体类型,对于观察者模式,仍不能完全消除类型依赖。通过泛型技术,设计了一种新的容器来完全消除观察者模式中的类型依赖,使任意类型的观察者都可以向目标注册。

2观察者角色的泛型实现

在观察者模式的通常实现中,所有具体观察者类都依赖Observer这一基类,通过泛型技术设计了一个类型无关的观察者容器类ObserverStub。ObserverStub有两个内部类EmptyType,Stub,以及一个成员函数m_content。EmptyType是一个“稻草人”基类,它不做具体工作,只为提供一个接口。Stub是EmptyType的子类,它实现了EmptyType的接口,并保存对真正观察者的引用,而它正是去除观察者模式类型依赖的关键所在。以下为观察者角色的具体实现。//目标类的桩类classObserverStub{public://构造函数为模板函数,用于传递类型信息template<typenameT>ObserverStub(constT&value):m_content(newStub<T>(value)){}//名称约定,给目标类提供一个回调函数voidupdate(){m_content->update();}private://纯虚类,定义接口classEmptyType{public:virtualvoidupdate()=0;};//桩类,保存真正的观察者template<typenameT>classStub:publicEmptyType{public:Stub(constT&value):m_stub(value){}//通知观察者voidupdate(){m_stub->update();}private://真正的观察者,类型由外部决定Tm_stub;};//观察者桩类的引用EmptyType*m_content;}

3目标类的实现

与通常的观察者模式一样,目标类也有一个数组型成员变量,不同的是它提供的注册接口attach是一个模板成员函数,类型T会通过编译器的类型推导技术一步步传导到Stub类,并在Stub类中保有一个与观察者同类型的引用m_stub。当目标状态发生变化时,观察者的桩类(ObserverStub)会首先得到通知,最终ObserverStub会把更新消息传导至真正的观察者m_stub,以下为目标类的具体实现。//目标类classSubject{public:...//状态更新时通知所有观察者voidnotify(){for(unsignedinti=0;i<m_stubVec.size();++i){m_stubVec[i]->update();}}//注册方法,为模板成员函数,可接受任意类型对象的注册template<typenameT>voidattach(To){m_stubVec.push_back(newObserverStub(o));}private://观察者引用数组std::vector<ObserverStub*>m_stubVec;};通过泛型技术,可以向外部隐藏上述细节与封装技术,观察者只需和通常一样向目标类注册,而不必知晓目标类如何存储对观察者的引用。对观察者的唯一要求是实现EmptyType中的名称约定,当然这一名称不必为update,而这是观察者必须付出的代价,因为作为观察者必须有一个方法来接收目标的状态更新通知。通过这一技术,在消除类型依赖的基础上,还保持了强类型语言的特点,观察者模式所有的参与者类型都会得到检验,而如果观察者类没有实现约定的方法,在编译就可以发现错误,避免了把类型错误推迟到运行期影响系统的运行。

4航天可视化遥操作子系统中的应用

在航天遥操作可视化子系统中,因为存在大量的用户界面设计工作,所以广泛应用了观察者模式,同时为了提高系统的开发效率,在系统的开发过程中使用了第三方库。系统设计之初,在继承第三方库提供的既有功能类时,必须同时继承一个观察者基类。通过泛型技术对观察者模式进行了重构[8-10],如图2所示。现在各个类如果想得到系统中二维点云(ViewPointItem)的位置变化通知,只需要提供一个接收通知的方法,各个类间不再有任何类型依赖。图中的TreeWidget等类都继承了第三方库中的既有对象,现在可以方便地使用第三方库,而不必再继承实现其它接口,同时观察者模式各对象仍和以前一样,在开发的过程中不必为这一重构付出代价,这样方法也有利于系统的扩展和新功能的添加,有新的类想接收目标的通知时,可以不再受类型约束。通过消除类型依赖,有效的提高了系统的可维护性和可扩展性。

5结束语

GoF虽然总结了各种设计模式的经典实现方案,但这些方案无法适用于所有情形,针对系统或语言的特定情况,应灵活地使用设计模式,在复用设计模式减少系统重新设计的基础上,让前人的设计经验更有效地复用于系统的开发工作之中。在航天可视化遥操作子系统的开发过程中,使用泛型技术对子系统中的观者模式进行了重构。实践表明,通过泛型技术消除观察者模式的类型依赖为系统带来了以下优点:观察者模式不必处在固定的类型系统中,其实现也变得整洁,易于维护。对于一些不支持多继承的语言,通过这一技术,仍可以在复用已有代码的基础上简单而优雅地使用观察者模式来解决问题。系统的可维护性和可扩展性也得到了提高。

作者:赵正旭 张登辉 刘甜 单位:石家庄铁道大学 信息科学与技术学院


    更多国内经济论文详细信息: 泛型技术消除观察者模式类型依赖探微
    http://www.400qikan.com/mflunwen/jjlw/gnjj/83444.html

    相关专题:怎样 安徽理工大学学报


    上一篇:教学过程下的高中物理论文
    下一篇:小学数学培养学生思维能力的方法

    认准400期刊网 可信 保障 安全 快速 客户见证 退款保证


    品牌介绍