设计模式之组合模式_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 设计模式之组合模式

设计模式之组合模式

 2013/7/29 19:09:25  xiaofengaini  程序员俱乐部  我要评论(0)
  • 摘要:软件开发中应该注意的事情有两点:1.多组合少继承继承虽说能简化代码,提高一定的复用性,但是对与代码耦合度影响较大2.多扩充少修改因新需求扩充新功能,而少修改已经通过测试的程式码。今天要介绍的就是组合模式,一种提供整体与部分的对照。这种理论很像树形,例如树中有树枝和树叶,树枝上有树叶,可以把树叶看做子节点,那么树枝也可以看成一个节点,但是这个节点和叶子节点的不同之处在于,其有子节点。另一个例子就是,公司中各个部门和群组然后处理相关商业需求逻辑,好比报表显示、读取资料...等
  • 标签:模式 设计 设计模式
软件开发中应该注意的事情有两点:
1.多组合少继承
继承虽说能简化代码,提高一定的复用性,但是对与代码耦合度影响较大
2.多扩充少修改
因新需求扩充新功能,而少修改已经通过测试的程式码。

今天要介绍的就是组合模式,一种提供整体与部分的对照。这种理论很像树形,例如树中有树枝和树叶,树枝上有树叶,可以把树叶看做子节点
,那么树枝也可以看成一个节点,但是这个节点和叶子节点的不同之处在于,其有子节点。另一个例子就是,公司中各个部门和群组

然后处理相关商业需求逻辑,好比报表显示、读取资料...等,
大多Client端可能要先依输入资料取得相对应部门物件,
这里面可能也有部门群组的判断处理(如处别又是另一种商业逻辑),
而且部门群组的异动也将会造成Client端程式码频繁修改,
导致Client端的耦合性很高、不容易维护...等,
为了将Client程式码解耦,我们透过组合模式,将物件组合成为简单层次结构,
让Client端可以使用一致的方法来处理组合物件就像处理个别物件一样(将一对多改为一对一),
并且自己可以处理自己复杂的商业逻辑,
下面我们实际来看一下组合模式可以帮Client程式码带来什么样的改善。


需求:依照部门处理相关商业逻辑

大多数人可能会这样写Client端程式码
String [] Departments={"DepA" ,"DepB","DepC","DepAll"}
Factory defactory=new Factory();
for(String depart in Departments)
{
  IDepProcess mydep=depfactory.getDep(depart);
   if (mydep is DepartmentA ) //单部门
                 {
                     //读资料
                     mydep . Process();
                }
                else if (mydep is DepartmentB )
                {
                    //更新资料
                     mydep . Process();
                }
                else if (mydep is DepartmentC )
                {
                    //删除资料
                     mydep . Process();
                }
                else if (mydep is DepartmentGroup ) //部门群组
                 {
                     //处别的处理
                    //先确认各部门人数..等
                    mydep . Process();
                     List < IDepProcess > mydeps = (mydep as DepartmentGroup ) . GetDepartments();
                     foreach ( IDepProcess dep in mydeps)
                    {
                        //if(dep is DepartmentA)....
                        //Client继续处理相关判断
                    }
                }
            }


public class Factory
     {
         public Factory() { }

        public IDepProcess GetDep( string Department)
        {
            IDepProcess _IDepProcess = null ;
             switch (Department)
            {
                case "DepA" :
                    _IDepProcess = new DepartmentA ();
                     break ;
                 case "DepB" :
                    _IDepProcess = new DepartmentB ();
                     break ;
                 case "DepC" :
                    _IDepProcess = new DepartmentC ();
                     break ;
                 case "DepAll" :
                    _IDepProcess = new DepartmentGroup ();
                     break ;
                 default :
                    _IDepProcess = new DepartmentA ();
                     break ;           
            }
            return _IDepProcess;
        }   
    }
接口

public interface IDepProcess
     {
         void Process();      
    }

public class DepartmentA  extends  IDepProcess
     {

        #region IDepProcess成员

        public void Process()
        {
            System.out.println( "部门A处理" );
        }

        #endregion
     }

    public class DepartmentB extends IDepProcess
     {

        #region IDepProcess成员

        public void Process()
        {
             System.out.println( "部门B处理" );
        }

        #endregion
     }

    public class DepartmentC extends IDepProcess
     {

        #region IDepProcess成员

        public void Process()
        {
             System.out.println( "部门C处理" );
        }

        #endregion
     }

    public class DepartmentGroup extends IDepProcess
     {
         protected List < IDepProcess > departments = new List < IDepProcess > ();
         public List < IDepProcess > GetDepartments()
        {
          return departments;
        }

        #region IDepProcess成员

        public void Process()
        {
            System.out.println( "组合部门处理" );
        }

        #endregion
     }


接下来使用组合模式来重构Client程式码
            IDepProcess mydep = new DepartmentGroup ();
            mydep . Add( new DepartmentA ());
            mydep . Add( new DepartmentB ());
            mydep . Add( new DepartmentC ());
            mydep . Process();


修改组合模式中抽象接口,用处叶子节点和组合节点
     public interface IDepProcess
     {
         void Process();
         void Add( IDepProcess DepProcess);
         void Remove( IDepProcess DepProcess);
    }


为了要处理子物件逻辑,所以增加2各方法(Add、Remove)

其他类别修改如下
public class DepartmentA extends IDepProcess
     {

        #region IDepProcess成员

        public void Process()
        {
            System.out.println( "部门A处理" );
        } 

        public void Add( IDepProcess DepProcess)
        {
             throw new UnsupportedOperationException("对象不支持这个功能");;
        }

        public void Remove( IDepProcess DepProcess)
        {
             throw new UnsupportedOperationException("对象不支持这个功能");
        }

        #endregion
     }

Add 和Remove 对于没有子部门(最底层)类别来说没有任何意义,所以抛出自定义讯息。

群组类别修改如下
public class DepartmentGroup extends IDepProcess
     {    
         protected List < IDepProcess > departments = new List < IDepProcess > ();

        #region IDepProcess成员

        public void Add( IDepProcess DepProcess)
        {
            departments . Add(DepProcess);
        }

        public void Remove( IDepProcess DepProcess)
        {
            departments . Remove(DepProcess);
        }     

        public void Process()
        {
            System.out.println( "组合部门处理" );      
             if (departments . Count > 0 )
            {
                foreach ( IDepProcess dep in departments)
                {
                    dep . Process(); //可能是子部门或其他部门
                 }
            }
        }

        #endregion      
     }



从应用角度来看,如果你想把一对多的关系,转换为一对一的关系(一致性的行为),
那么你可以看到组合模式所带来的好处。
发表评论
用户名: 匿名