zoukankan      html  css  js  c++  java
  • JAVA设计模式初探之组合模式

    先看看组合模式的定义吧:“将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

       就拿剪发办卡的事情来分析一下吧。

       首先,一张卡可以在总部,分店,加盟店使用,那么总部可以刷卡,分店也可以刷卡,加盟店也可以刷卡,这个属性结构的店面层级关系就明确啦。

       那么,总店刷卡消费与分店刷卡消费是一样的道理,那么总店与分店对会员卡的使用也具有一致性。

     1.组合模式的例子

    那么组合模式的实例如下:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. public class ComponentDemo {  
    5.     public abstract class Component {  
    6.         String name;  
    7.   
    8.         public abstract void add(Component c);  
    9.   
    10.         public abstract void remove(Component c);  
    11.   
    12.         public abstract void eachChild();  
    13.     }  
    14.   
    15.     // 组合部件类  
    16.     public class Leaf extends Component {  
    17.   
    18.         // 叶子节点不具备添加的能力,所以不实现  
    19.         @Override  
    20.         public void add(Component c) {  
    21.             // TODO Auto-generated method stub  
    22.             System.out.println("");  
    23.         }  
    24.   
    25.         // 叶子节点不具备添加的能力必然也不能删除  
    26.         @Override  
    27.         public void remove(Component c) {  
    28.             // TODO Auto-generated method stub  
    29.             System.out.println("");  
    30.         }  
    31.   
    32.         // 叶子节点没有子节点所以显示自己的执行结果  
    33.         @Override  
    34.         public void eachChild() {  
    35.             // TODO Auto-generated method stub  
    36.             System.out.println(name + "执行了");  
    37.         }  
    38.   
    39.     }  
    40.   
    41.     // 组合类  
    42.     public class Composite extends Component {  
    43.   
    44.         // 用来保存节点的子节点  
    45.         List<Component> list = new ArrayList<Component>();  
    46.   
    47.         // 添加节点 添加部件  
    48.         @Override  
    49.         public void add(Component c) {  
    50.             // TODO Auto-generated method stub  
    51.             list.add(c);  
    52.         }  
    53.   
    54.         // 删除节点 删除部件  
    55.         @Override  
    56.         public void remove(Component c) {  
    57.             // TODO Auto-generated method stub  
    58.             list.remove(c);  
    59.         }  
    60.   
    61.         // 遍历子节点  
    62.         @Override  
    63.         public void eachChild() {  
    64.             // TODO Auto-generated method stub  
    65.             System.out.println(name + "执行了");  
    66.             for (Component c : list) {  
    67.                 c.eachChild();  
    68.             }  
    69.         }  
    70.     }  
    71.   
    72.     public static void main(String[] args) {  
    73.         ComponentDemo demo = new ComponentDemo();  
    74.         // 构造根节点  
    75.         Composite rootComposite = demo.new Composite();  
    76.         rootComposite.name = "根节点";  
    77.   
    78.         // 左节点  
    79.         Composite compositeLeft = demo.new Composite();  
    80.         compositeLeft.name = "左节点";  
    81.   
    82.         // 构建右节点,添加两个叶子几点,也就是子部件  
    83.         Composite compositeRight = demo.new Composite();  
    84.         compositeRight.name = "右节点";  
    85.         Leaf leaf1 = demo.new Leaf();  
    86.         leaf1.name = "右-子节点1";  
    87.         Leaf leaf2 = demo.new Leaf();  
    88.         leaf2.name = "右-子节点2";  
    89.         compositeRight.add(leaf1);  
    90.         compositeRight.add(leaf2);  
    91.   
    92.         // 左右节点加入 根节点  
    93.         rootComposite.add(compositeRight);  
    94.         rootComposite.add(compositeLeft);  
    95.         // 遍历组合部件  
    96.         rootComposite.eachChild();  
    97.     }  
    98. }  


    执行结果如下:

    2.应用组合模式的会员卡消费

            那么我们就根据我们会员卡的消费,来模拟一下组合模式的实现吧!let's go!

            首先:

                   1.我们的部件有,总店,分店,加盟店!

                   2.我们的部件共有的行为是:刷会员卡

                   3.部件之间的层次关系,也就是店面的层次关系是,总店下有分店、分店下可以拥有加盟店。

            有了我们这几个必要条件后,我的要求就是目前店面搞活动当我在总店刷卡后,就可以累积相当于在所有下级店面刷卡的积分总额,设计的代码如下:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. public class PayDemo {  
    5.   
    6.     public abstract class Market {  
    7.         String name;  
    8.   
    9.         public abstract void add(Market m);  
    10.   
    11.         public abstract void remove(Market m);  
    12.   
    13.         public abstract void PayByCard();  
    14.     }  
    15.   
    16.     // 分店 下面可以有加盟店  
    17.     public class MarketBranch extends Market {  
    18.         // 加盟店列表  
    19.         List<Market> list = new ArrayList<PayDemo.Market>();  
    20.   
    21.         public MarketBranch(String s) {  
    22.             this.name = s;  
    23.         }  
    24.   
    25.         @Override  
    26.         public void add(Market m) {  
    27.             // TODO Auto-generated method stub  
    28.             list.add(m);  
    29.         }  
    30.   
    31.         @Override  
    32.         public void remove(Market m) {  
    33.             // TODO Auto-generated method stub  
    34.             list.remove(m);  
    35.         }  
    36.   
    37.         // 消费之后,该分店下的加盟店自动累加积分  
    38.         @Override  
    39.         public void PayByCard() {  
    40.             // TODO Auto-generated method stub  
    41.             System.out.println(name + "消费,积分已累加入该会员卡");  
    42.             for (Market m : list) {  
    43.                 m.PayByCard();  
    44.             }  
    45.         }  
    46.     }  
    47.   
    48.     // 加盟店 下面不在有分店和加盟店,最底层  
    49.     public class MarketJoin extends Market {  
    50.         public MarketJoin(String s) {  
    51.             this.name = s;  
    52.   
    53.         }  
    54.   
    55.         @Override  
    56.         public void add(Market m) {  
    57.             // TODO Auto-generated method stub  
    58.   
    59.         }  
    60.   
    61.         @Override  
    62.         public void remove(Market m) {  
    63.             // TODO Auto-generated method stub  
    64.   
    65.         }  
    66.   
    67.         @Override  
    68.         public void PayByCard() {  
    69.             // TODO Auto-generated method stub  
    70.             System.out.println(name + "消费,积分已累加入该会员卡");  
    71.         }  
    72.     }  
    73.   
    74.     public static void main(String[] args) {  
    75.         PayDemo demo = new PayDemo();  
    76.           
    77.         MarketBranch rootBranch = demo.new MarketBranch("总店");  
    78.         MarketBranch qhdBranch = demo.new MarketBranch("秦皇岛分店");  
    79.         MarketJoin hgqJoin = demo.new MarketJoin("秦皇岛分店一海港区加盟店");  
    80.         MarketJoin btlJoin = demo.new MarketJoin("秦皇岛分店二白塔岭加盟店");  
    81.           
    82.         qhdBranch.add(hgqJoin);  
    83.         qhdBranch.add(btlJoin);  
    84.         rootBranch.add(qhdBranch);  
    85.         rootBranch.PayByCard();  
    86.     }  
    87. }  


    运行结果如下:

      这样在累积所有子店面积分的时候,就不需要去关心子店面的个数了,也不用关系是否是叶子节点还是组合节点了,也就是说不管是总店刷卡,还是加盟店刷卡,都可以正确有效的计算出活动积分。

          3.什么情况下使用组合模式

           引用大话设计模式的片段:“当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。”

    作者:jason0539

    微博:http://weibo.com/2553717707

    博客:http://blog.csdn.net/jason0539(转载请说明出处)

  • 相关阅读:
    27. Remove Element
    26. Remove Duplicates from Sorted Array
    643. Maximum Average Subarray I
    674. Longest Continuous Increasing Subsequence
    1. Two Sum
    217. Contains Duplicate
    448. Find All Numbers Disappeared in an Array
    566. Reshape the Matrix
    628. Maximum Product of Three Numbers
    UVa 1349 Optimal Bus Route Design (最佳完美匹配)
  • 原文地址:https://www.cnblogs.com/telwanggs/p/6780461.html
Copyright © 2011-2022 走看看