Composite(结构型模式——组合模式)

引入:
在面对对象系统时,我们常常会遇到一类具有“容器”特征的对象——即它们在充当对象的同时也是其他对象的容器。
例如:

public interface IBox
{
    
    
    void Process();
}
public class SingleBox : IBox
{
    
    
    public void Process()
    {
    
    
    }
}

Container(容器特征对象):里面可能包括SingleBox对象和其他Container对象

/容器特征的对象
public class ContainerBox : IBox
{
    
    
    private ArrayList list = null;

    public void Add(Ibox box)
    {
    
    
        if (list == null)
        {
    
    
            list = new ArrayList();
        }

        list.Add(box);
    }

    public void Remove(Ibox box)
    {
    
    
        if (list == null)
            throw new Exception();
        list.Remove(box);
    }
    public void Process()
    {
    
    
        //做自己的处理
    }

    public ArrayList getBoxes()
    {
    
    
        //...
        return new ArrayList();
    }
}

这时的调用

//客户代码与对象内部结构耦合,希望只与IBox耦合
public void UseBox()
{
    
    
    IBox box = Factory.GetBox();
    if (box is ContainerBox)//依赖对象内部结构
    {
    
    
        box.Process();
        ArrayList list = ((ContainerBox)box).getBoxes();
        //...将面临比较复杂的处理
    }
    else if(box is SingleBox)
    {
    
    
        box.Process();
    }
}

组合模式
动机

在这里插入图片描述
意图

在这里插入图片描述
树形结构:对比上方的例子,其中SingleBox即为树型结构的叶子,ContainerBox为树枝。
结构(与代码相结合)
在这里插入图片描述
改进后代码
Ibox

public interface Ibox
{
    
    
   void Process();
   void Add(Ibox box);
   void Remove(Ibox box);
}

Singlebox

public class Singlebox : Ibox
{
    
    
    public void Process()
    {
    
    
    }
    public void Add(Ibox box)
    {
    
    
        //抛出异常
         throw new XXXXException();
    }
    public void Remove(Ibox box)
    {
    
    
        //抛出异常
        throw new XXXXException();
    }
}

Containerbox

public class Containerbox :  Ibox
{
    
    
    private ArrayList list = null;

    public void Add(Ibox box)
    {
    
    
        if (list == null)
        {
    
    
            list = new ArrayList();
        }
        list.Add(box);
    }

    public void Remove(Ibox box)
    {
    
    
        if (list == null)
            throw new Exception();
        list.Remove(box);
    }
    public void Process()
    {
    
    
        //做自己的处理
        //添加下方来取代GetBox()
        if (list != null)
        {
    
    
            foreach (Ibox box in list)
            {
    
    
                box.Process();
            }
        }
    }

使用

public class Uses
{
    
    
    //客户代码与对象内部结构耦合,希望只与IBox耦合
    public void UseBox()
    {
    
    
        IBox box = Factory.GetBox();
        box.Process();
    }
}

其中,Containerbox中的Add()和Remove()方法处理有两种
1、像上面例子把Add()和Remove()方法放到接口Ibox中,但Singlebox不实现这两个方法,在具体实现时抛出异常。【违反单一职责原则】
2、将Add()和Remove()方法只放到Cintainerbox类中,这样在使用时需要获取Ibox代表的具体类的类型,就像第一个代码一样。
在具体项目中,使用哪种根据项目需求,第一种安全性更高,第二种透明性更好。

要点
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_51565051/article/details/131570983
今日推荐