組合模式

      組合模式容許用戶將對象組合成樹形結構來表現「總體/部分」的層次結構,從而可以以一致的方式處理單個對象以及對象組合。根據這個定義,首先可以想到的就是軟件的菜單,一個菜單能夠包含菜單項(菜單項是指再也不包含其餘內容的菜單條目),也能夠包含帶有其餘菜單項的菜單,所以使用組合模式描述菜單就很恰當,咱們的需求是針對一個菜單,打印出其包含的全部菜單以及菜單項。ide

      首先,無論是菜單仍是菜單項,都應該繼承自統一的接口,這裏姑且將這個統一的接口稱爲菜單組件,其定義以下:測試

 1 public abstract class MenuComponent {
 2   public void add(MenuComponent menuComponent){
 3     throw new UnsupportedOperationException();
 4   }
 5 
 6   public void remove(MenuComponent menuComponent){
 7     throw new UnsupportedOperationException();
 8   }
 9 
10   public MenuComponent getChild(int i){
11     throw new UnsupportedOperationException();
12   }
13 
14   public String getName(){
15     throw new UnsupportedOperationException();
16   }
17 
18   public String getDescription(){
19     throw new UnsupportedOperationException();
20   }
21 
22   public void print(){
23     throw new UnsupportedOperationException();
24   }
25 }
MenuComponent

      這裏選擇抽象類來實現MenuComponent,是由於須要對一些方法給出默認實現,如此一來,Menu和MenuItem類就能夠只覆蓋本身感興趣的方法,而不用搭理不須要或者不感興趣的方法,舉例來講,Menu類能夠包含子菜單,所以須要覆蓋add()、remove()、getChild()方法,可是MenuItem就不該該有這些方法。這裏給出的默認實現是拋出異常,你也能夠根據本身的須要改寫默認實現。this

      接下來定義菜單類Menu:spa

 1 public class Menu extends MenuComponent{
 2   private List<MenuComponent> menuComponentList;
 3   private String name;
 4   private String descrition;
 5 
 6   public Menu(String name, String description){
 7     this.name = name;
 8     this.descrition = description;
 9     menuComponentList = new ArrayList<>();
10   }
11 
12   @Override
13   public void add(MenuComponent menuComponent){
14     menuComponentList.add(menuComponent);
15   }
16 
17   @Override
18   public void remove(MenuComponent menuComponent){
19     menuComponentList.remove(menuComponent);
20   }
21 
22   @Override
23   public MenuComponent getChild(int i){
24     return menuComponentList.get(i);
25   }
26 
27   @Override
28   public String getName() {
29     return name;
30   }
31 
32   @Override
33   public String getDescription(){
34     return descrition;
35   }
36 
37   @Override
38   public void print(){
39     System.out.println(getName() + ", " + getDescription());
40     Iterator iterator = menuComponentList.iterator();
41     while(iterator.hasNext()){
42       MenuComponent menuComponent = (MenuComponent) iterator.next();
43       menuComponent.print();
44     }
45   }
46 }
Menu

      Menu類應該覆蓋本身感興趣的方法,實際上這裏它覆蓋了父類的全部方法,這樣作的緣由僅僅是由於抽象類中的全部方法都是該類須要的,假設某一天咱們在MenuComponent裏面增長了color()方法,該方法只針對菜單項顯示灰色底色,那麼Menu累就不該該覆蓋color()方法了。code

      讓咱們接着來實現MenuItem:對象

 1 public class MenuItem extends MenuComponent{
 2   private String name;
 3   private String descrition;
 4 
 5   public MenuItem(String name, String descrition){
 6     this.name = name;
 7     this.descrition = descrition;
 8   }
 9 
10   @Override
11   public String getName() {
12     return name;
13   }
14 
15   @Override
16   public String getDescription(){
17     return descrition;
18   }
19 
20   @Override
21   public void print(){
22     System.out.println(getName() + ", " + getDescription());
23   }
24 }
MenuItem

      MenuItem只覆蓋了getName()、getDescription()、print()方法,由於其餘的方法對該類並不適用。blog

      如今能夠寫個測試類看一下組合模式在菜單上面的表現了:繼承

 1 public class MenuComponentTest {
 2   public static void main(String[] args){
 3     MenuComponentTest test = new MenuComponentTest();
 4     MenuComponent allMenu = test.createMenu();
 5     allMenu.print();
 6   }
 7 
 8   public MenuComponent createMenu(){
 9     MenuComponent fileMenu = new Menu("文件", "文件相關選項");
10     fileMenu.add(new MenuItem("設置", "能夠更改一些設置項"));
11     fileMenu.add(new MenuItem("保存", "保存全部文件"));
12 
13     MenuComponent saveAsMenu = new Menu("另存爲", "另存爲其餘一些格式");
14     saveAsMenu.add(new MenuItem("PDF", "另存爲PDF格式"));
15     saveAsMenu.add(new MenuItem("docx","另存爲docx格式"));
16     fileMenu.add(saveAsMenu);
17 
18     MenuComponent helpMenu = new Menu("幫助","一些輔助項");
19     helpMenu.add(new MenuItem("關於咱們","軟件製做方的一些消息"));
20     helpMenu.add(new MenuItem("幫助中心","電話和郵箱諮詢"));
21 
22     MenuComponent allMenu = new Menu("全部菜單","包含全部菜單的菜單");
23     allMenu.add(fileMenu);
24     allMenu.add(helpMenu);
25 
26     return allMenu;
27   }
28 }

      打印結果爲(沒有縮進因此稍微醜了一點):接口

全部菜單, 包含全部菜單的菜單
文件, 文件相關選項
設置, 能夠更改一些設置項
保存, 保存全部文件
另存爲, 另存爲其餘一些格式
PDF, 另存爲PDF格式
docx, 另存爲docx格式
幫助, 一些輔助項
關於咱們, 軟件製做方的一些消息
幫助中心, 電話和郵箱諮詢

      最後回顧一下這個菜單的例子,類之間的關係以下:ip

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息