外贸网站建设推广公司,少儿图书销售网站开发背景,莱芜融媒体中心网站,电商第三方平台有哪些使用组合模式#xff08;Composite Pattern#xff09;是一个更优雅的方式来表示菜单和菜单项。组合模式允许我们将单个对象#xff08;如菜单项#xff09;和组合对象#xff08;如菜单#xff09;以相同的方式处理。
解决方案#xff1a;
创建组合结构#xff1a;我…使用组合模式Composite Pattern是一个更优雅的方式来表示菜单和菜单项。组合模式允许我们将单个对象如菜单项和组合对象如菜单以相同的方式处理。
解决方案
创建组合结构我们将菜单项和菜单抽象为 MenuComponent其中菜单项是叶节点菜单是组合节点。Menu 类可以包含子菜单或菜单项。MenuItem 类代表具体的菜单项。Waitress 类只需处理一个 MenuComponent 对象并能够遍历所有的菜单和菜单项。
代码实现
1. 创建抽象类 MenuComponent
import java.util.Iterator;public abstract class MenuComponent {public void add(MenuComponent menuComponent) {throw new UnsupportedOperationException();}public void remove(MenuComponent menuComponent) {throw new UnsupportedOperationException();}public MenuComponent getChild(int i) {throw new UnsupportedOperationException();}public String getName() {throw new UnsupportedOperationException();}public String getDescription() {throw new UnsupportedOperationException();}public double getPrice() {throw new UnsupportedOperationException();}public void print() {throw new UnsupportedOperationException();}public IteratorMenuComponent createIterator() {throw new UnsupportedOperationException();}
}2. 实现 MenuItem 类叶节点
public class MenuItem extends MenuComponent {private String name;private String description;private double price;public MenuItem(String name, String description, double price) {this.name name;this.description description;this.price price;}Overridepublic String getName() {return name;}Overridepublic String getDescription() {return description;}Overridepublic double getPrice() {return price;}Overridepublic void print() {System.out.println( getName() : getDescription() -- ¥ getPrice());}
}3. 实现 Menu 类组合节点
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class Menu extends MenuComponent {private ListMenuComponent menuComponents new ArrayList();private String name;private String description;public Menu(String name, String description) {this.name name;this.description description;}Overridepublic void add(MenuComponent menuComponent) {menuComponents.add(menuComponent);}Overridepublic void remove(MenuComponent menuComponent) {menuComponents.remove(menuComponent);}Overridepublic MenuComponent getChild(int i) {return menuComponents.get(i);}Overridepublic String getName() {return name;}Overridepublic String getDescription() {return description;}Overridepublic void print() {System.out.println(\n getName() : getDescription());System.out.println(---------------------);for (MenuComponent menuComponent : menuComponents) {menuComponent.print();}}
}4. 实现 Waitress 类
public class Waitress {private MenuComponent allMenus;public Waitress(MenuComponent allMenus) {this.allMenus allMenus;}public void printMenu() {allMenus.print();}
}5. 修改测试代码
public class CompositePatternDemo {public static void main(String[] args) {MenuComponent breakfast new Menu(早餐菜单, 早餐6:009:00);MenuComponent lunch new Menu(午餐菜单, 午餐11:3014:30);MenuComponent coffeeMenu new Menu(咖啡菜单, 全天24小时供应);MenuComponent allMenus new Menu(所有菜单, 所有可使用的菜单);// Add breakfast itemsbreakfast.add(new MenuItem(胡辣汤, 素胡辣汤, 3));breakfast.add(new MenuItem(油条, 按斤称, 2));breakfast.add(new MenuItem(包子, 莲藕馅, 1.5));// Add lunch itemslunch.add(new MenuItem(茄汁面, 番茄鸡蛋汤面, 8));lunch.add(new MenuItem(蒜汁面, 凉拌面, 7));lunch.add(new MenuItem(臊子面, 羊肉臊子面, 15));// Add coffee itemscoffeeMenu.add(new MenuItem(生椰拿铁, 少冰, 9.99));coffeeMenu.add(new MenuItem(丝绒拿铁, 热饮, 12.99));coffeeMenu.add(new MenuItem(茉莉生椰拿铁, 外卖少冰不另外加糖, 16.99));// Combine menusallMenus.add(breakfast);allMenus.add(lunch);allMenus.add(coffeeMenu);// Create waitress and print all menusWaitress waitress new Waitress(allMenus);waitress.printMenu();}
}输出结果
所有菜单: 所有可使用的菜单
---------------------早餐菜单: 早餐6:009:00
---------------------胡辣汤: 素胡辣汤 -- ¥3.0油条: 按斤称 -- ¥2.0包子: 莲藕馅 -- ¥1.5午餐菜单: 午餐11:3014:30
---------------------茄汁面: 番茄鸡蛋汤面 -- ¥8.0蒜汁面: 凉拌面 -- ¥7.0臊子面: 羊肉臊子面 -- ¥15.0咖啡菜单: 全天24小时供应
---------------------生椰拿铁: 少冰 -- ¥9.99丝绒拿铁: 热饮 -- ¥12.99茉莉生椰拿铁: 外卖少冰不另外加糖 -- ¥16.99代码解释
MenuComponent 抽象类定义了菜单和菜单项的通用操作如 add()、remove()、getChild() 等。组合对象Menu可以包含 MenuComponent而叶节点MenuItem则只处理具体的菜单项。Menu 类可以包含子菜单或菜单项通过组合来管理多个菜单和子菜单。MenuItem 类叶节点表示具体的菜单项。Waitress 类只需要处理一个 MenuComponent 对象无论是叶节点菜单项还是组合对象菜单都可以通过相同的方式处理并打印。
总结
通过使用组合模式Menu 和 MenuItem 都被视为 MenuComponentWaitress 只需要一个 MenuComponent 对象即可遍历所有菜单和菜单项。这使得代码非常灵活易于扩展和维护。
组合模式 (Composite Pattern) 详细解释
1. 组合模式的概念
组合模式允许我们将对象组合成树形结构来表示“部分-整体”的层次结构。它使得客户端能够以一致的方式处理单个对象和组合对象。
在我们的场景中菜单项MenuItem是基本的元素菜单Menu则是组合对象可以包含其他菜单或菜单项。Waitress 类不需要知道它是在处理菜单还是菜单项只要调用通用接口即可这正是组合模式的强大之处。
2. 类结构概述 MenuComponent抽象基类提供了所有菜单和菜单项的通用操作。它定义了组合和叶节点的接口如 add()、remove()、getChild()、print() 等操作。 由于菜单项不需要支持 add() 或 getChild()而菜单可以包含其他菜单或菜单项因此这些操作在基类中默认抛出 UnsupportedOperationException具体的子类可以根据需要覆盖这些方法。 Menu组合对象类代表一个菜单可以包含多个 MenuComponent既可以是子菜单也可以是菜单项。它的主要功能是管理子菜单和菜单项提供添加、删除、获取子组件的操作。 MenuItem叶节点类代表一个具体的菜单项。它没有子节点所以不能包含其他 MenuComponent只能提供自己的基本信息如名称、描述和价格。 Waitress客户端类接收一个 MenuComponent可以遍历和打印所有菜单和菜单项。它对组合和叶节点一视同仁只调用 print() 方法即可打印出菜单结构。
3. 组合模式的工作原理
通过 MenuComponent 抽象类Waitress 可以直接使用 MenuComponent 的统一接口来处理菜单和菜单项的组合结构。组合模式的核心在于它让我们能够像处理单个对象一样处理整个对象的组合。无论是遍历单个菜单项还是遍历包含多个子菜单的菜单Waitress 类只需要关心调用通用的 print() 方法。
4. 组合模式的优点 一致性客户端可以一致地处理叶节点菜单项和组合节点菜单使得客户端代码变得简洁且灵活。 在我们实现的 Waitress 类中它只关心如何遍历和打印 MenuComponent不需要区分是在处理一个具体的菜单项还是一个包含子菜单的组合对象。 可扩展性添加新的菜单或菜单项变得非常简单。我们可以在组合中嵌套更多的子菜单也可以轻松添加新的菜单项甚至在 Menu 中组合多个 Menu。 简化客户端代码由于客户端只需要处理抽象基类 MenuComponent不需要分别处理 MenuItem 和 Menu客户端代码变得非常简洁。这种设计也让系统变得更灵活和可维护。
5. 组合模式中的递归
组合模式的核心在于它是一个递归结构菜单可以包含子菜单子菜单又可以包含更多的菜单或菜单项。这种递归结构允许我们通过遍历树形结构来处理所有的菜单项。Menu 的 print() 方法就是递归调用遍历所有子菜单和菜单项。
6. 与迭代器模式的对比
虽然组合模式和迭代器模式都能处理多个对象但它们的目标和使用场景有所不同 迭代器模式用于顺序遍历一个集合中的元素通常用在结构较为扁平的情况下例如遍历数组或列表中的元素。之前的实现中我们通过多个 Iterator 来遍历不同菜单这更适合扁平化的数据结构。 组合模式适合处理树形结构如菜单-子菜单-菜单项在这种情况下组合模式能够让客户端以统一的方式处理复杂的层次结构。