漫谈设计模式 —— 结构的封装

上一篇文章谈了一些对创建行为封装的模式,还有一些模式他们是在结构层面来封装的,分别有外观模式、适配器模式、代理模式、装饰者模式、组合模式、桥梁模式与蝇量模式。什么是在结构层面封装呢?我们可以先简单的理解为在一个原有的类上面再包了一个类。那为什么要这样做呢?这样做可以达到很多灵活的变化,我们首先来看最直观也是最简单的,就是改变接口。

用一个类包裹一个原有的类,从而改变它的接口,这就是适配器(Adapter)模式。举个简单的例子,假设我们游戏中特效管理器已经有一个在场景内指定坐标播放特效的接口SFXMgr::PlaySceneSFX(int nX, int nY, int nZ)。现在我们有一个新需求是通过D3DVECTOR传递坐标,那我们第一个想法就是重载PlaySceneSFX,提供SFXMgr::PlaySceneSFX(const D3DVECTOR& vPosition)接口。如果再来一个需求,是在场景内一个物件脚下播放特效,这样我们又得重载一个SFXMgr::PlaySceneSFX(const SceneObject* pObject)接口。这样做不但把特效管理器改乱了,而且特效管理器还要看见D3DVECTOR和SceneObject。为了解决这样的问题我们可以写一个SFXMgrAdapter包裹着SFXMgr,然后由SFXMgrAdapter提供各种各样的接口,最后完成转换后调用到SFXMgr::PlaySceneSFX接口完成真正的功能。

适配器模式就是通过包裹一个原有的类,提供客户期待的接口,这样不需要改动到原来的类,也不用客户完成调用的转换细节。适配器有两种实现方式:类适配器和对象适配器。其实就是我们所说的“包裹”是以何种方法实现的。类适配器通过继承来包裹原有的类,提供新接口。对象适配器则通过组合,拥有原有类的一个实例。两种适配器都是为了改变接口,并且最终功能都是在原有类中完成,属于改变接口但不改变行为。

Continue reading