迭代器模式&组合模式
1.迭代器:统一形式访问聚合对象中元素,不暴露内部表示;取出元素没有次序,next() 不代表+1
可以编写多态的代码搭配
内部的:由迭代器自身控制 next()
外部的:客户决定next(),调用,实现
组合:当有数个对象的集合,彼此之间有“整体/部分”关系,想用一致的方式对待这些对象时;(比如图形 Frame 内含小widget...,都需要show())
2.代码
C++
1 //composite c++ 2 #include <iostream> 3 #include <string> 4 #include <vector> 5 using namespace std; 6 7 class Component{ 8 public: 9 Component(string str): m_str(str){} 10 virtual void add(Component*) = 0; 11 virtual void display(int ) = 0; 12 13 string m_str; 14 }; 15 16 class Leaf : public Component{ 17 public: 18 Leaf(string strName): Component(strName){} 19 void add(Component* comp){ cout<<"can`t add in leaf"<<endl; } 20 void display(int nDepth){ 21 string tStr; 22 for(int i = 0;i<nDepth;i++) tStr += "-"; 23 tStr += m_str; 24 cout<<tStr<<endl; 25 } 26 }; 27 28 class Composite : public Component{ 29 public: 30 Composite(string str):Component(str){} 31 void add(Component* pComp){ 32 m_component.push_back(pComp); 33 } 34 void display(int nDepth){ 35 string tStr; 36 for(int i = 0;i<nDepth;i++) tStr += "-"; 37 38 tStr += m_str; 39 cout<<tStr<<endl; 40 // 41 vector<Component*>::iterator it = m_component.begin(); 42 while(it != m_component.end()){ 43 (*it)->display(nDepth + 2); 44 it++; 45 } 46 } 47 private: 48 vector<Component*> m_component; 49 }; 50 51 int main(){ 52 Component* p_root = new Composite("root"); 53 p_root->add(new Leaf("leaf_1")); 54 p_root->add(new Leaf("leaf_2")); 55 56 Component* p_L1 = new Composite("node_1"); 57 p_L1->add(new Leaf("node_1_1")); 58 p_L1->add(new Leaf("node_1_2")); 59 p_root->add(p_L1); 60 61 p_root->display(0); 62 63 return 0; 64 }
Java:
1 //interator java 2 import java.util.ArrayList; 3 import java.util.Iterator; 4 import java.util.Stack; 5 //CompositeIterator 6 class CompositeIterator implements Iterator<MenuComponent>{ 7 Stack<Iterator<MenuComponent>> stack = new Stack<Iterator<MenuComponent>>(); 8 public CompositeIterator(Iterator<MenuComponent> iterator){ 9 stack.push(iterator); 10 } 11 public MenuComponent next(){ 12 if(hasNext()){ 13 Iterator<MenuComponent> iterator = stack.peek(); 14 MenuComponent component = iterator.next(); 15 if(component instanceof Menu){ 16 stack.push(component.createIterator()); 17 } 18 return component; 19 } 20 else{ 21 return null; 22 } 23 } 24 public boolean hasNext(){ 25 if(stack.empty()){ 26 return false; 27 }else{ 28 Iterator<MenuComponent> iterator = stack.peek(); 29 if(!iterator.hasNext()){ 30 stack.pop(); 31 return hasNext(); 32 }else{ 33 return true; 34 } 35 } 36 } 37 public void remove(){ 38 throw new UnsupportedOperationException(); 39 } 40 } 41 class NullIterator implements Iterator<MenuComponent>{ 42 public MenuComponent next(){ 43 return null; 44 } 45 public boolean hasNext(){ 46 return false; 47 } 48 public void remove(){ 49 throw new UnsupportedOperationException(); 50 } 51 } 52 53 //MenuComponent 54 abstract class MenuComponent{ 55 public void add(MenuComponent menuComponent){ 56 throw new UnsupportedOperationException(); 57 } 58 public void remove(MenuComponent menuComponent){ 59 throw new UnsupportedOperationException(); 60 } 61 public MenuComponent getChild(int i){ 62 throw new UnsupportedOperationException(); 63 } 64 public String getName(){ 65 throw new UnsupportedOperationException(); 66 } 67 public String getDescription(){ 68 throw new UnsupportedOperationException(); 69 } 70 public double getPrice(){ 71 throw new UnsupportedOperationException(); 72 } 73 public boolean isVegetarian(){ 74 throw new UnsupportedOperationException(); 75 } 76 public void print(){ 77 throw new UnsupportedOperationException(); 78 } 79 //use it to composite all child 80 public Iterator<MenuComponent> createIterator(){ 81 throw new UnsupportedOperationException(); 82 } 83 } 84 85 // 86 class MenuItem extends MenuComponent{ 87 String name; 88 String description; 89 boolean vegetarian; 90 double price; 91 92 public MenuItem(String name, 93 String description, 94 boolean vegetarian, 95 double price) 96 { 97 this.name = name; 98 this.description = description; 99 this.vegetarian = vegetarian; 100 this.price = price; 101 } 102 public String getName(){ 103 return this.name; 104 } 105 public String getDescription(){ 106 return this.description; 107 } 108 public boolean isVegetarian(){ 109 return vegetarian; 110 } 111 public double getPrice(){ 112 return this.price; 113 } 114 public void print(){ 115 System.out.print(" " + getName()); 116 if(isVegetarian()){ 117 System.out.print("(v)"); 118 } 119 System.out.println(", Price: " + getPrice()); 120 System.out.println(" - - " + getDescription()); 121 } 122 public Iterator<MenuComponent> createIterator(){ 123 return new NullIterator(); //use null object 124 } 125 } 126 //Menu is a composite 127 class Menu extends MenuComponent{ 128 ArrayList<MenuComponent> menuComponents = new ArrayList<MenuComponent>(); 129 String name; 130 String description; 131 132 public Menu(String name,String description){ 133 this.name = name; 134 this.description = description; 135 } 136 public void add(MenuComponent menuComponent){ 137 menuComponents.add(menuComponent); 138 } 139 public void remove(MenuComponent menuComponent){ 140 menuComponents.remove(menuComponent); 141 } 142 public MenuComponent getChild(int i){ 143 return menuComponents.get(i); 144 } 145 public String getName(){ 146 return name; 147 } 148 public String getDescription(){ 149 return description; 150 } 151 public void print(){ 152 System.out.print("\n" + getName()); 153 System.out.println(", " + getDescription()); 154 System.out.println("- - - - - - - - - - - - - - - - - "); 155 //use iterator 156 Iterator<MenuComponent> iterator = menuComponents.iterator(); 157 while(iterator.hasNext()){ 158 MenuComponent menuComponent = iterator.next(); 159 menuComponent.print(); 160 } 161 } 162 public Iterator<MenuComponent> createIterator(){ 163 return new CompositeIterator(menuComponents.iterator()); 164 } 165 } 166 167 //Waitress 168 class Waitress{ 169 MenuComponent allMenus; 170 171 public Waitress(MenuComponent allMenus){ 172 this.allMenus = allMenus; 173 } 174 public void printMenu(){ 175 allMenus.print(); 176 } 177 public void printVegetarianMenu(){ 178 Iterator<MenuComponent> iterator = allMenus.createIterator(); 179 System.out.println("\nVEGETTARIAN MENU\n - - - "); 180 while(iterator.hasNext()){ 181 MenuComponent menuComponent = iterator.next(); 182 try{ 183 if(menuComponent.isVegetarian()){ 184 menuComponent.print(); 185 } 186 }catch(UnsupportedOperationException e){} 187 } 188 } 189 } 190 191 //main 192 class iterator_composite{ 193 public static void main(String[] args){ 194 195 MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU","Break fast"); 196 MenuComponent dinerMenu = new Menu("DINER MENU" ,"Lunch" ); 197 MenuComponent dessert = new Menu("DESSERT MENU" ,"Sessert" ); 198 199 MenuComponent allMenus = new Menu("ALL MENUS","All menus combined"); 200 allMenus.add(pancakeHouseMenu); 201 allMenus.add(dinerMenu); 202 allMenus.add(dessert); 203 204 //add:pancakeHouseMenu 205 pancakeHouseMenu.add(new MenuItem("K&B's Pancake Breakfast", 206 "Pancakes with scrambled eggs,and toast", 207 true, 208 1.99)); 209 pancakeHouseMenu.add(new MenuItem("Regular Pancake Breakfast", 210 "Pancakes with fried eggs,sausage", 211 false, 212 2.99)); 213 //add:dinerMenu 214 dinerMenu.add(new MenuItem("Vegetarian BLT", 215 "Bacon with lettuce & tomato on whole wheat", 216 true, 217 1.99)); 218 dinerMenu.add(new MenuItem("Soup of the day", 219 "Soup of the day,with a side of potato salad", 220 false, 221 2.66)); 222 dinerMenu.add(new MenuItem("Hotdog", 223 "with saurkraut,relish,onions,topped with cheese", 224 false, 225 3.05)); 226 //add:dessert 227 dessert.add(new MenuItem("Pasta", 228 "with Marinara Sauce,and a slice of sourdough bread", 229 true, 230 0.99)); 231 // 232 Waitress waitress = new Waitress(allMenus); 233 waitress.printMenu(); 234 waitress.printVegetarianMenu(); 235 } 236 }
3.杂记:
(1)一个类应该只有一个引起变化的原因,高内聚,一个责任指派一个类
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通