Java设计模式笔记之合成模式

1.合成模式

合成(Composite)模型模式属于对象的结构模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素和复合元素同等看待。


2.模式结构

Java设计模式笔记之合成模式_第1张图片

(1)抽象构件(Component):抽象角色,定义所有单纯构件和复合构件的共同行为。

(2)树叶(leaf):没有子构件的单纯构件

(3)树枝(Composite):复合构件,包含有子构件。

合成必须要在合适的地方提供管理子构件的方法,有2种方法:

一是在Component中定义管理方法,add(),remove(),以及getChild()等。客户端可以同等操作树叶和树枝,但是在树叶中的这些方法没有意义。

二是在Composite中定义管理方法,客户端需要区别对待树叶和树枝。


3.模式实现举例

绘图软件中,线、长方形和圆形是基本图形,还有一些复杂的图形由这些基本图形组成,适用合成模式。

(1)第一种实现方式,管理方法定义在Component中

Java设计模式笔记之合成模式_第2张图片


代码:

Graphics.java

abstract public class Graphics
{
    public abstract void draw();

    public abstract void add(Graphics g);

    public abstract void remove(Graphics g);

    public abstract Graphics getChild(int i);
}

Line.java(树叶)

public class Line extends Graphics 
{
    public void draw()
    {
    	System.out.println("draw Line");
    }

    /*
     * 以下是管理子项的空实现
     */
    public void add(Graphics g)
    {
        //do nothing
    }

    public void remove(Graphics g)
    {
        //do nothing
    }

    public Graphics getChild(int i)
    {
        return null;
    }
}

Circle.java(树叶)

public class Circle extends Graphics 
{
    public void draw()
    {
        System.out.println("draw Circle");
    }

    public void add(Graphics g)
    {
        //do nothing
    }

    public void remove(Graphics g)
    {
        //do nothing
    }

    public Graphics getChild(int i)
    {
        return null;
    }
}

Picture.java(树枝)

import java.util.Vector;

public class Picture extends Graphics 
{
    private Vector list = new Vector(10);

    public void draw()
    {
        for (int i = 0 ; i < list.size(); i++)
        {
			Graphics g = (Graphics) list.get(i);

            g.draw();
        }
    }

    public void add(Graphics g)
    {
        list.add(g);
    }

    public void remove(Graphics g)
    {
        list.remove(g);
    }

    public Graphics getChild(int i)
    {
        return (Graphics) list.get(i);
    }
}


(2)第二种实现方式,子构件管理方法在Composite树枝中

Java设计模式笔记之合成模式_第3张图片


源码:

Graphics.java

abstract public class Graphics
{
    public abstract void draw();
}

Line.java

public class Line extends Graphics 
{
    public void draw()
    {
        System.out.println("draw a line");
    }
}

Picture.java

import java.util.Vector;

public class Picture extends Graphics 
{
    private Vector list = new Vector(10);

    public void draw()
    {
        for (int i = 0 ; i < list.size(); i++)
        {
			Graphics g = (Graphics) list.get(i);

            g.draw();
        }
    }

    public void add(Graphics g)
    {
        list.add(g);
    }

    public void remove(Graphics g)
    {
        list.remove(g);
    }

    public Graphics getChild(int i)
    {
        return (Graphics) list.get(i);
    }
}


4.合成模式实现说明

(1) 如果子构件需要与父构件通信,在子构件中可以保持父构件的一个引用。但是在管理时,需要维护这个引用;

(2)有时系统需要遍历一个树枝构件的子构件很多次,可以把遍历结果存放到父构件中;

(3)示例中存放子构件的容器是Vector,实际中也可以使用别的;

(4)客户端不应当直接调用树叶类,应当由其父类向树叶类进行委派。


你可能感兴趣的:(设计模式)