设计模式实践-adapter
1、 提出背景
在做一个项目时,出现这样一个需求。我需要删除某个容器里面的某种类型的控件。例如在图1中,我需要删除窗口上的Label控件。
图1 测试窗口(CollectionTestForm)
窗口或容器的控件集合属性Controls是从IList接口继承的,IList中只提供了一种删除函数Remove(object value),而我需要的是删除某种类型控件,即Remove(Type type)的功能,其中参数type是要删除控件的类型。这样就需要提供一种新的结构来实现新的功能需求――删除某种类型对象。于是采用了Adapter模式。
2、 功能模型
其中,ITypeList包括新的功能需求Remove(Type type)。TypeList是ITypeList的一个具体实现。按照对象类型Adapter的模型,TypeList还包含了一个IList类型的field,通过构造子对其赋值。在Remove(Type type)的具体实现中,还是调用了IList的原有操作。具体实现可参见下面的代码实例。
在这里是对IList接口进行功能增加,使用类Adapter是不合适的,否则将在TypeList中产生大量的冗余函数。如果各位专家有什么不同看法,请告知。
3、 代码实例
{
void Remove(Type type);
}
public class TypeList : ITypeList
{
IList list;
public TypeList(IList collection)
{
list = collection;
}
public ArrayList GetList(Type type)
{
ArrayList tmp = new ArrayList();
foreach (object o in list)
{
if (o.GetType() == type)
tmp.Add(o);
}
return tmp;
}
public void Remove(Type type)
{
foreach (object o in GetList(type))
{
list.Remove(o);
}
}
}
[TestClass()]
public class TypeListTest
{
[TestMethod()]
public void RemoveTest()
{
CollectionTestForm frm = new CollectionTestForm();
IList collection = frm.Controls;
TypeList list = new TypeList(collection);
list.Remove(typeof(Label));
Assert.AreEqual(2,collection.Count);
Assert.AreEqual(typeof(Button), collection[0].GetType());
}
}
其中CollectionTestForm的外观如图1所示
4、 思想总结
在遇到这个问题之初,想当然的认为应该使用Decorator Pattern。但是经过进一步考虑,这里需要的是增加新的接口,并不是在原有接口的基础上进行增强。这就非adapter莫属了。这也是adapter和Decorator的根本区别。
在我的文章中,没有提到对Adapter模式的介绍,如果有需要的朋友,可以参考吕震宇老师的文章http://www.cnblogs.com/zhenyulu/articles/39386.html,或其他相关书籍。
5、 参考文献
阎宏,《Java与模式》,电子工业出版社
[美]Robert C. Martin,《敏捷软件开发-原则、模式与实践》,清华大学出版社