组合模式

上一篇 / 下一篇  2009-09-16 09:54:51 / 个人分类:.NET设计模式

意图

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。[GOF《设计模式》]

我们以JUnit中的TestCase和TestSuit为例来说明组合模式,在JUnit中,TestCase是最小的一个测试用例,而TestSuit称为测试包,顾名思义,它可以包含其他的TestCase或TestSuit,但是,无论是TestCase还是TestSuit,都继承自TestCaseBase这个类,而且运行他们都是调用Run这个方法,我们看一下(我这里写的可能与JUnit不一样,但思路基本一样):

    public abstract class TestCaseBase
    {
        public abstract void Run();
    }

    public abstract class TestCase : TestCaseBase
    {
        public abstract void Init();
        public abstract void CleanUp();
        public abstract void TestMethod();

        public override void Run()
        {
            Init();
            TestMethod();
            CleanUp();
        }
    }

    public class TestSuit : TestCaseBase
    {
        private List<TestCaseBase> caseList = new List<TestCaseBase>();

        public void Add(TestCaseBase testCase)
        {
            caseList.Add(testCase);
        }

        public void Remove(TestCaseBase testCase)
        {
            caseList.Remove(testCase);
        }

        public override void Run()
        {
            foreach (TestCaseBase elem in caseList)
                elem.Run();
        }
    }

效果及实现要点

1Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

2.将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。

3Composite模式中,是将“AddRemove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。ASP.NET控件的实现在这方面为我们提供了一个很好的示范。

4Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

适用性

以下情况下适用Composite模式:

1.你想表示对象的部分-整体层次结构

2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

总结

组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。


TAG:

 

评分:0

我来说两句

Open Toolbar