当我们必须使用对象的树状分层结构时,复合设计模式非常有用。
它使我们能够统一对待单个对象和对象的组成。 它属于结构设计模式的范畴,因为它将对象组合成树形结构以表示部分整个层次结构。
UML表示形式:
复合模式的UML表示形式如下:
哪里:
- 组件:是接口或抽象类 ,它是所有类集的超类型
- 复合类:它定义Component的具体实现并保存其他子组件的实例
- 叶子类:叶子表示非复合类型,即它不是由其他组件组成的
请注意, 一个合成对象可以包含其他合成对象,这通常被称为递归合成。
此外, Leaf和Composite类都实现(扩展为抽象类) Component接口。 这使我们能够通过多态统一地处理复合对象和非复合对象。
叶子和复合对象符合Component中定义的一组共享行为。
实施复合模式:
让我们构建一个UI菜单层次结构,其中每个菜单都可以具有子菜单。 我们将使用复合设计模式来实现此层次结构。
首先,让我们定义MenuComponent类:
public abstract class MenuComponent {private String name;private String url;//constructor, getters, setterspublic void add(MenuComponent component) {throw new UnsupportedOperationException();}public abstract void displayMenu();
}
我们希望统一处理聚合的菜单和单个菜单项,因此我们在MenuComponent类中抽象了displayMenu()方法。
现在让我们实现MenuItem类:
public class MenuItem extends MenuComponent {public MenuItem(String name, String url) {super(name, url);}@Overridepublic void displayMenu() {System.out.println(getName() + " : " + getUrl());}
}
MenuItem将是leaf元素,并且不能包含任何子菜单。
另一方面, Menu由MenuComponent对象组成。 换句话说, 菜单可以同时包含Menu和MenuItem对象:
public class Menu extends MenuComponent {List<MenuComponent> subMenus = new ArrayList<>();public Menu(String name, String url) {super(name, url);}@Overridepublic void add(MenuComponent menuComponent) {this.subMenus.add(menuComponent);}@Overridepublic void displayMenu() {System.out.println(getName() + " : " + getUrl() + "\n");this.subMenus.forEach(MenuComponent::displayMenu);}
}
测试我们的实施:
客户端代码应与MenuComponent抽象一起使用。 让我们创建菜单项的层次结构:
MenuComponent allTutorials = new Menu("Tutorials", "/tutorials");MenuComponent spring = new Menu("Spring", "/spring");
MenuComponent versioning = new Menu("Version Management", "/versioning");MenuComponent java = new MenuItem("Java", "/java");allTutorials.add(spring);
allTutorials.add(versioning);
allTutorials.add(java);spring.add(new MenuItem("Spring Core", "/core"));
spring.add(new MenuItem("Spring Boot", "/boot"));MenuComponent git = new Menu("Git", "/git");MenuComponent svn = new MenuItem("SVN", "/svn"); versioning.add(svn);
versioning.add(git);git.add(new MenuItem("Introduction to Git", "/intro"));
git.add(new MenuItem("Github Integration", "/github"));allTutorials.displayMenu();
上面的代码将产生以下输出:
Tutorials:/tutorialsSpring:/springSpring Core : /core
Spring Boot : /bootVersion Management:/versioningSVN : /svn
Git:/gitIntroduction to Git : /intro
Github Integration : /githubJava : /java
结论:
在本教程中,我们探索了复合设计模式。 这是一种结构模式,在尝试创建对象的层次结构时会派上用场。 它有助于我们对复合对象和非复合对象进行统一处理。
翻译自: https://www.javacodegeeks.com/2019/08/composite-design-pattern-in-java.html