[原创]设计模型探索L-composite parttern之玉树临风

[原创]设计模型探索L-composite parttern之玉树临风
组合模式:允许你将对象组合成树型结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合.
      Composite模式涉及的是一组对象,其中有些对象可能含有其他的对象;因此,有些对象可能代表一个对象群组,而其他的则是单个对象,即叶子。利用Composite模式建模包含两个重要的建模概念。其中一个重要的思想是所设计的群组即能包含单个个体,还要能包含其他群组(一个常见的错误是所设计的群组只能包含叶子)。另一个重要的概念是要定义出单个对象和对象组合的公共特性。结合这两个概念,我们可以定义即适合群组又适合单个个体的通用类型,然后将群组建模成具有这种类型的对象的集合。

      Composite模式的设计意图在于:让用户能够用统一的接口处理单个对象以及对象组合.
组合模式的组成部份:
    1.抽象组件
    2.组件节点
    3.叶节点
 组合模式的各组成部份之间的关系:

例子:
抽象组件:

package  composite;

import  java.util.Iterator;

/** */ /**
 * <ul>
 * <li>Title:[MilitaryPerson]</li>
 * <li>Description: [军人抽象组件]</li>
 * <li>Copyright 2009 Upengs Co., Ltd.</li>
 * <li>All right reserved.</li>
 * <li>Created by [Huyvanpull] [2011-8-2]</li>
 * <li>Midified by [modifier] [modified time]</li>
 * </ul>
 * 
 * 
@version 1.0
 
*/

public   interface  MilitaryPerson
{
    
/** *//**
     * <ul>
     * <li>Description:[添加组件]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@param person
     
*/

    
public void add(MilitaryPerson person);
    
    
/** *//**
     * <ul>
     * <li>Description:[删除组件]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@param person
     
*/

    
public void remove(MilitaryPerson person);
    
    
/** *//**
     * <ul>
     * <li>Description:[得到子节点]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@param index
     * 
@return
     
*/

    
public MilitaryPerson getChild(int index);
    
    
/** *//**
     * <ul>
     * <li>Description:[得到所有节点]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@return
     
*/

    
public Iterator<MilitaryPerson> getAllChildren();
    
    
/** *//**
     * <ul>
     * <li>Description:[是否叶节点]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@return
     
*/

    
public boolean isLeaf();
    
    
/** *//**
     * <ul>
     * <li>Description:[得到薪水]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@return
     
*/

    
public double getSalary();
    
    
/** *//**
     * <ul>
     * <li>Description:[设置薪水]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
     * 
@param salary
     * 
@return
     
*/

    
public double setSalary(double salary);
}


组件节点:

package  composite;

import  java.util.ArrayList;
import  java.util.Iterator;
import  java.util.List;

/** */ /**
 * <ul>
 * <li>Title:[MilitaryOfficer]</li>
 * <li>Description: [军官]</li>
 * <li>Copyright 2009 Upengs Co., Ltd.</li>
 * <li>All right reserved.</li>
 * <li>Created by [Huyvanpull] [2011-8-2]</li>
 * <li>Midified by [modifier] [modified time]</li>
 * </ul>
 * 
@version 1.0  
 
*/

public   class  MilitaryOfficer  implements  MilitaryPerson
{
    
/** *//** 姓名 */
    
public String name;
    
    
/** *//** 薪水 */
    
public double salary;
    
    
/** *//** 组件容器 */
    
private List<MilitaryPerson> militaryPersonLst;
    
    
/** *//**
     *<ul>
     *<li>Description:[构造方法]</li>
     *<ul>
     * 
@param name
     * 
@param salary
     
*/

    
public MilitaryOfficer(String name, double salary)
    
{
        
this.name = name;
        
this.salary = salary;
        
this.militaryPersonLst = new ArrayList<MilitaryPerson>();
    }

    
    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#add(composite.MilitaryPerson)
     
*/

    
public void add(MilitaryPerson person)
    
{
        
this.militaryPersonLst.add(person);
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getAllChildren()
     
*/

    
public Iterator<MilitaryPerson> getAllChildren()
    
{
        
return this.militaryPersonLst.iterator();
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getChild(int)
     
*/

    
public MilitaryPerson getChild(int index)
    
{
        
return this.militaryPersonLst.get(index);
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getSalary()
     
*/

    
public double getSalary()
    
{
        
return salary;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#isLeaf()
     
*/

    
public boolean isLeaf()
    
{
        
return false;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#remove(composite.MilitaryPerson)
     
*/

    
public void remove(MilitaryPerson person)
    
{
        
this.militaryPersonLst.remove(person);
        
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#setSalary(double)
     
*/

    
public double setSalary(double salary)
    
{
        
return salary;
    }
   

}



叶结点:

package  composite;

import  java.util.Iterator;

/** */ /**
 * <ul>
 * <li>Title:[MilitarySoldier]</li>
 * <li>Description: [士兵]</li>
 * <li>Copyright 2009 Upengs Co., Ltd.</li>
 * <li>All right reserved.</li>
 * <li>Created by [Huyvanpull] [2011-8-2]</li>
 * <li>Midified by [modifier] [modified time]</li>
 * </ul>
 * 
@version 1.0  
 
*/

public   class  MilitarySoldier  implements  MilitaryPerson
{
    
/** *//** 姓名 */
    
public String name;
    
    
/** *//** 薪水 */
    
public double salary;
    
    
/** *//**
     *<ul>
     *<li>Description:[构造方法]</li>
     *<ul>
     * 
@param name
     * 
@param salary
     
*/

    
public MilitarySoldier(String name, double salary)
    
{
        
this.name = name;
        
this.salary = salary;
    }

    
    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#add(composite.MilitaryPerson)
     
*/

    
public void add(MilitaryPerson person)
    
{
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getAllChildren()
     
*/

    
public Iterator<MilitaryPerson> getAllChildren()
    
{
        
return null;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getChild(int)
     
*/

    
public MilitaryPerson getChild(int index)
    
{
        
return null;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#getSalary()
     
*/

    
public double getSalary()
    
{
        
return salary;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#isLeaf()
     
*/

    
public boolean isLeaf()
    
{
        
return true;
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#remove(composite.MilitaryPerson)
     
*/

    
public void remove(MilitaryPerson person)
    
{
    }


    
/**//* (non-Javadoc)
     * @see composite.MilitaryPerson#setSalary(double)
     
*/

    
public double setSalary(double salary)
    
{
        
return salary;
    }
   

}



计算程序(和模式无关的):

package  composite;

import  java.util.Iterator;

public   class  CalcSalary
{
    
/** *//**
     * <ul>
     * <li>Description:[计算薪水方法]</li>
     * <li>Created by [Huyvanpull] [2011-8-2]</li>
     * <li>Midified by [modifier] [modified time]</li>
     * </ul>
     * 
@param person
     * 
@return
     
*/

    
public static double calcSalary(MilitaryPerson person)
    
{
        
double sumSalary = person.getSalary();
        
if (!person.isLeaf())
        
{
            Iterator
<MilitaryPerson> iterator = person.getAllChildren();
            
while (iterator.hasNext())
            
{
                MilitaryPerson militaryPerson 
= iterator.next();
                sumSalary 
+= militaryPerson.getSalary();
            }

        }

        
return sumSalary;
    }

}



测试:

 

package  composite;

public   class  Test
{   
    
public static void main(String[] args)
    
{
        
// 上将
        MilitaryPerson general = new MilitaryOfficer("上将"100000);
        
        
// 上校
        MilitaryPerson colonel1 = new MilitaryOfficer("上校1"80000);
        MilitaryPerson colonel2 
= new MilitaryOfficer("上校2"80000);
        general.add(colonel1);
        general.add(colonel2);
        
        
// 上尉
        MilitaryPerson captain1 = new MilitaryOfficer("上尉1"60000);
        MilitaryPerson captain2 
= new MilitaryOfficer("上尉2"60000);
        colonel1.add(captain1);
        colonel1.add(captain2);
        
        
        MilitaryPerson captain3 
= new MilitaryOfficer("上尉3"60000);
        MilitaryPerson captain4 
= new MilitaryOfficer("上尉4"60000);
        colonel2.add(captain3);
        colonel2.add(captain4);
        
        
// 士兵
        MilitarySoldier airman1 = new MilitarySoldier("士兵"10000);
        MilitarySoldier airman2 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman3 
= new MilitarySoldier("士兵"10000);
        captain1.add(airman1);
        captain1.add(airman2);
        captain1.add(airman3);
        
        MilitarySoldier airman4 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman5 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman6 
= new MilitarySoldier("士兵"10000);
        captain2.add(airman4);
        captain2.add(airman5);
        captain2.add(airman6);
        
        MilitarySoldier airman7 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman8 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman9 
= new MilitarySoldier("士兵"10000);
        captain3.add(airman7);
        captain3.add(airman8);
        captain3.add(airman9);
        
        MilitarySoldier airman10 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman11 
= new MilitarySoldier("士兵"10000);
        MilitarySoldier airman12 
= new MilitarySoldier("士兵"10000);
        captain4.add(airman10);
        captain4.add(airman11);
        captain4.add(airman12);
        
        System.out.println(
"上将编制内的所有人员的薪水:" + CalcSalary.calcSalary(general));
        System.out.println(
"上尉1编制内的所有人员的薪水:" + CalcSalary.calcSalary(colonel1));
        System.out.println(
"上校2编制内的所有人员的薪水:" + CalcSalary.calcSalary(captain1));
    }

}

 

要点:

1. 组合模式以不遵守单一责任原则换取透明性,让Client将组合和叶节点一视同仁。

2. 在实现组合模式时,有很多设计上的折衷。要根据需求平衡透明性和安全性。

3. 有时候系统需要遍历一个树枝构件的子构件很多次,这时候可以把遍历结果缓存起来。

4. 组合模式的实现中,可以让子对象持有父对象的引用进行反向追溯。

 

优点:

1. 组合模式可以很容易的增加新的构件。

2. 使用组合模式可以使客户端变的很容易设计,因为客户端可以对组合和叶节点一视同仁。

缺点:

1. 使用组合模式后,控制树枝构件的类型不太容易。

2. 用继承的方法来增加新的行为很困难。

你可能感兴趣的:([原创]设计模型探索L-composite parttern之玉树临风)