博客
关于我
组合模式
阅读量:397 次
发布时间:2019-03-06

本文共 4087 字,大约阅读时间需要 13 分钟。

      组合模式允许用户将对象组合成树形结构来表现“整体/部分”的层次结构,从而能够以一致的方式处理单个对象以及对象组合。根据这个定义,首先能够想到的就是软件的菜单,一个菜单可以包含菜单项(菜单项是指不再包含其他内容的菜单条目),也可以包含带有其他菜单项的菜单,因此使用组合模式描述菜单就很恰当,我们的需求是针对一个菜单,打印出其包含的所有菜单以及菜单项。

      首先,不管是菜单还是菜单项,都应该继承自统一的接口,这里姑且将这个统一的接口称为菜单组件,其定义如下:

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就不应该有这些方法。这里给出的默认实现是抛出异常,你也可以根据自己的需要改写默认实现。

      接下来定义菜单类Menu:

1 public class Menu extends MenuComponent{ 2   private List
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 @Override13 public void add(MenuComponent menuComponent){14 menuComponentList.add(menuComponent);15 }16 17 @Override18 public void remove(MenuComponent menuComponent){19 menuComponentList.remove(menuComponent);20 }21 22 @Override23 public MenuComponent getChild(int i){24 return menuComponentList.get(i);25 }26 27 @Override28 public String getName() {29 return name;30 }31 32 @Override33 public String getDescription(){34 return descrition;35 }36 37 @Override38 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()方法了。

      让我们接着来实现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   @Override11   public String getName() {12     return name;13   }14 15   @Override16   public String getDescription(){17     return descrition;18   }19 20   @Override21   public void print(){22     System.out.println(getName() + ", " + getDescription());23   }24 }
MenuItem

      MenuItem只覆盖了getName()、getDescription()、print()方法,因为其他的方法对该类并不适用。

      现在可以写个测试类看一下组合模式在菜单上面的表现了:

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格式帮助, 一些辅助项关于我们, 软件制作方的一些消息帮助中心, 电话和邮箱咨询

      最后回顾一下这个菜单的例子,类之间的关系如下:

 

转载地址:http://klkkz.baihongyu.com/

你可能感兴趣的文章
一个系统部署多个tomcat实例
查看>>
HP服务器设置iLO
查看>>
从头实现一个WPF条形图
查看>>
.NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐)
查看>>
使用QT实现一个简单的登陆对话框(纯代码实现C++)
查看>>
QT :warning LNK4042: 对象被多次指定;已忽略多余的指定
查看>>
GLFW 源码 下载-编译-使用/GLAD配置
查看>>
针对单个网站的渗透思路
查看>>
Typescript 学习笔记六:接口
查看>>
【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现
查看>>
02、MySQL—数据库基本操作
查看>>
OpenJDK1.8.0 源码解析————HashMap的实现(一)
查看>>
MySQL-时区导致的时间前后端不一致
查看>>
2021-04-05阅读小笔记:局部性原理
查看>>
go语言简单介绍,增强了解
查看>>
python file文件操作--内置对象open
查看>>
架构师入门:搭建基本的Eureka架构(从项目里抽取)
查看>>
MongoDB 快速扫盲贴
查看>>
修复搜狗、360等浏览器不识别SameSite=None 引起的单点登录故障
查看>>
EXTJS4.2——10.Tab+Iframe
查看>>