经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式之迭代器与组合模式(四)
来源:cnblogs  作者:小酒窝  时间:2019/6/27 9:30:49  对本文有异议

因为这系列篇幅较长,所以在这里也不进行任何铺垫,直奔主题去啦。

利用组合设计菜单

我们要如何在菜单上应用组合模式呢?一开始,我们需要创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。换句话说,我们可以针对菜单或菜单项调用相同的方法。

让我们从头来看看如何让菜单能够符合组合模式的结构:

实现菜单组件

好了,我们开始编写菜单组件的抽象类;请记住,菜单组件的角色是为叶节点和组合节点提供一个共同的接口。

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

让我们来看菜单类。别忘了,这是组合类图里的叶类,它实现组合内元素的行为。

  1. public class MenuItem extends MenuComponent {
  2. String name;
  3. String description;
  4. boolean vegetarian;
  5. double price;
  6. public MenuItem(String name,
  7. String description,
  8. boolean vegetarian,
  9. double price)
  10. {
  11. this.name = name;
  12. this.description = description;
  13. this.vegetarian = vegetarian;
  14. this.price = price;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public String getDescription() {
  20. return description;
  21. }
  22. public double getPrice() {
  23. return price;
  24. }
  25. public boolean isVegetarian() {
  26. return vegetarian;
  27. }
  28. public Iterator<MenuComponent> createIterator() {
  29. return new NullIterator();
  30. }
  31. public void print() {
  32. System.out.print(" " + getName());
  33. if (isVegetarian()) {
  34. System.out.print("(v)");
  35. }
  36. System.out.println(", " + getPrice());
  37. System.out.println(" -- " + getDescription());
  38. }
  39. }

我们已经有了菜单项,还需要组合类,这就是我们叫做菜单的。别忘了,此组合类可以持有菜单项或其他菜单。

  1. public class Menu extends MenuComponent {
  2. Iterator<MenuComponent> iterator = null;
  3. ArrayList<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
  4. String name;
  5. String description;
  6. public Menu(String name, String description) {
  7. this.name = name;
  8. this.description = description;
  9. }
  10. public void add(MenuComponent menuComponent) {
  11. menuComponents.add(menuComponent);
  12. }
  13. public void remove(MenuComponent menuComponent) {
  14. menuComponents.remove(menuComponent);
  15. }
  16. public MenuComponent getChild(int i) {
  17. return menuComponents.get(i);
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public String getDescription() {
  23. return description;
  24. }
  25. public Iterator<MenuComponent> createIterator() {
  26. if (iterator == null) {
  27. iterator = new CompositeIterator(menuComponents.iterator());
  28. }
  29. return iterator;
  30. }
  31. public void print() {
  32. System.out.print("\n" + getName());
  33. System.out.println(", " + getDescription());
  34. System.out.println("---------------------");
  35. }
  36. }

因为菜单是一个组合,包含了菜单项和其他的菜单,所以它的print()应该打印出它所包含的一切。如果它不这么做,我们就必须遍历整个组合的每个节点,然后将每一项打印出来。这么一来,也就失去了使用组合结构的意义

所以,print还得进行优化,如下:

  1. public void print() {
  2. System.out.print("\n" + getName());
  3. System.out.println(", " + getDescription());
  4. System.out.println("---------------------");
  5. Iterator<MenuComponent> iterator = menuComponents.iterator();
  6. while (iterator.hasNext()) {
  7. MenuComponent menuComponent = iterator.next();
  8. menuComponent.print();
  9. }
  10. }

看到上面了没,我们用了迭代器。用它遍历所有菜单组件,遍历过程中,可能遇到其他菜单,或者是遇到菜单项。由于菜单和菜单项都实现了print,那我们只要调用print即可。

开始测试数据之前,我们了解一下,在运行时菜单组合是什么样的:

开始运行我们的测试程序啦:

  1. public class MenuTestDrive {
  2. public static void main(String args[]) {
  3. MenuComponent pancakeHouseMenu =
  4. new Menu("PANCAKE HOUSE MENU", "Breakfast");
  5. MenuComponent dinerMenu =
  6. new Menu("DINER MENU", "Lunch");
  7. MenuComponent cafeMenu =
  8. new Menu("CAFE MENU", "Dinner");
  9. MenuComponent dessertMenu =
  10. new Menu("DESSERT MENU", "Dessert of course!");
  11. MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
  12. allMenus.add(pancakeHouseMenu);
  13. allMenus.add(dinerMenu);
  14. allMenus.add(cafeMenu);
  15. pancakeHouseMenu.add(new MenuItem(
  16. "K&B's Pancake Breakfast",
  17. "Pancakes with scrambled eggs, and toast",
  18. true,
  19. 2.99));
  20. pancakeHouseMenu.add(new MenuItem(
  21. "Regular Pancake Breakfast",
  22. "Pancakes with fried eggs, sausage",
  23. false,
  24. 2.99));
  25. pancakeHouseMenu.add(new MenuItem(
  26. "Blueberry Pancakes",
  27. "Pancakes made with fresh blueberries, and blueberry syrup",
  28. true,
  29. 3.49));
  30. pancakeHouseMenu.add(new MenuItem(
  31. "Waffles",
  32. "Waffles, with your choice of blueberries or strawberries",
  33. true,
  34. 3.59));
  35. dinerMenu.add(new MenuItem(
  36. "Vegetarian BLT",
  37. "(Fakin') Bacon with lettuce & tomato on whole wheat",
  38. true,
  39. 2.99));
  40. dinerMenu.add(new MenuItem(
  41. "BLT",
  42. "Bacon with lettuce & tomato on whole wheat",
  43. false,
  44. 2.99));
  45. dinerMenu.add(new MenuItem(
  46. "Soup of the day",
  47. "A bowl of the soup of the day, with a side of potato salad",
  48. false,
  49. 3.29));
  50. dinerMenu.add(new MenuItem(
  51. "Hotdog",
  52. "A hot dog, with saurkraut, relish, onions, topped with cheese",
  53. false,
  54. 3.05));
  55. dinerMenu.add(new MenuItem(
  56. "Steamed Veggies and Brown Rice",
  57. "A medly of steamed vegetables over brown rice",
  58. true,
  59. 3.99));
  60. dinerMenu.add(new MenuItem(
  61. "Pasta",
  62. "Spaghetti with Marinara Sauce, and a slice of sourdough bread",
  63. true,
  64. 3.89));
  65. dinerMenu.add(dessertMenu);
  66. dessertMenu.add(new MenuItem(
  67. "Apple Pie",
  68. "Apple pie with a flakey crust, topped with vanilla icecream",
  69. true,
  70. 1.59));
  71. dessertMenu.add(new MenuItem(
  72. "Cheesecake",
  73. "Creamy New York cheesecake, with a chocolate graham crust",
  74. true,
  75. 1.99));
  76. dessertMenu.add(new MenuItem(
  77. "Sorbet",
  78. "A scoop of raspberry and a scoop of lime",
  79. true,
  80. 1.89));
  81. cafeMenu.add(new MenuItem(
  82. "Veggie Burger and Air Fries",
  83. "Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
  84. true,
  85. 3.99));
  86. cafeMenu.add(new MenuItem(
  87. "Soup of the day",
  88. "A cup of the soup of the day, with a side salad",
  89. false,
  90. 3.69));
  91. cafeMenu.add(new MenuItem(
  92. "Burrito",
  93. "A large burrito, with whole pinto beans, salsa, guacamole",
  94. true,
  95. 4.29));
  96. Waitress waitress = new Waitress(allMenus);
  97. waitress.printVegetarianMenu();
  98. }
  99. }

结果这里就不附上了,请大家自行去跑代码实现吧。相信你们又对组合模式也已经有了一个大概了吧。下一篇,还有更犀利的,组合迭代器等着我们。小编马上回去搞起来,安排上。

爱生活,爱学习,爱感悟,爱挨踢

原文链接:http://www.cnblogs.com/dimple91/p/11089204.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号