• 《Head First 设计模式》学习笔记——迭代模式 + 组合模式


    迭代模式设置共生死亡,一般来说。我们只是想实现一个集,我们需要的同时提供这个集合的迭代器,喜欢java中间Collection。List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这种新的容器,当然也须要引入迭代器模式。给我们的容器实现一个迭代器。————题记

    设计模式
    迭代器模式:提供一种方法顺序訪问一个聚合对象中的各个元素,而不暴露其内部的表示。

    把游走的任务放在迭代器上。而不是聚合上。

    这样简化了聚合的接口和实现。也让责任各得其所。


    组合模式:同意你将对象组合成树形结构来表现“总体/部分”分层结构。组合能让客户以一致的方式处理个别对象以及对象组合。

    使用组合结构。我们能把同样的操作应用在组合和个别对象上。

    换句话说,在大多数情况下。我们能够忽略对象组合和个别对象之间的区别。


    设计原则
    单一责任:一个类应该仅仅有一个引起变化的原因。


    要点
    迭代器同意訪问聚合的元素,而不须要暴露他的内部结构。
    迭代器将遍历聚合的工作封装到一个对象中。
    迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时。就能够使用多态机制。

    组合模式同意客户对个别对象和组合对象一视同仁。
    在实现组合模式时,有很多设计上的折中,你要依据须要平衡透明性和安全性。

    模型匹配
    策略模型          封装可互换的相位,并使用托付决定使用哪一个
    适配器模型      改变一个或多个类的接口
    迭代器模型      提供一个方式来遍历集合。而无需暴露集合的实现
    外观模型         简化一群类的接口
    组合模型         客户能够将对象的集合以及个别对象一视同仁
    观察者模型      当某个状态改变时,同意一群对象能被通知到

    迭代器模式:
    //定义迭代器接口
    public interface Iterator {
    	boolean hasNext();
    	Object next();
    }
    
    // implements 实现详细接口
    public class DinerMenuIterator implements Iterator {
    	MenuItem[] items;
    	int position = 0;
     
    	public DinerMenuIterator(MenuItem[] items) {
    		this.items = items;
    	}
     
    	public Object next() {
    		MenuItem menuItem = items[position];
    		position = position + 1;
    		return menuItem;
    	}
     
    	public boolean hasNext() {
    		if (position >= items.length || items[position] == null) {
    			return false;
    		} else {
    			return true;
    		}
    	}
    }
    
    
    public class DinerMenu implements Menu {
    	static final int MAX_ITEMS = 6;
    	int numberOfItems = 0;
    	MenuItem[] menuItems;
      
    	public DinerMenu() {
    		menuItems = new MenuItem[MAX_ITEMS];
     
    		addItem("Vegetarian BLT",
    			"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
    		addItem("BLT",
    			"Bacon with lettuce & tomato on whole wheat", false, 2.99);
    		addItem("Soup of the day",
    			"Soup of the day, with a side of potato salad", false, 3.29);
    		addItem("Hotdog",
    			"A hot dog, with saurkraut, relish, onions, topped with cheese",
    			false, 3.05);
    		addItem("Steamed Veggies and Brown Rice",
    			"Steamed vegetables over brown rice", true, 3.99);
    		addItem("Pasta",
    			"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
    			true, 3.89);
    	}
      
    	public void addItem(String name, String description, 
    	                     boolean vegetarian, double price) 
    	{
    		MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
    		if (numberOfItems >= MAX_ITEMS) {
    			System.err.println("Sorry, menu is full!  Can't add item to menu");
    		} else {
    			menuItems[numberOfItems] = menuItem;
    			numberOfItems = numberOfItems + 1;
    		}
    	}
    
    	//返回迭代器接口
    	public Iterator createIterator() {
    		return new DinerMenuIterator(menuItems);
    	}
     
    	// other menu methods here
    }
    
    
    package net.dp.iterator.dinermerger;
    
    public class Waitress {
    	PancakeHouseMenu pancakeHouseMenu;
    	DinerMenu dinerMenu;
     
    	//在构造器中,女招待照应两个菜单
    	public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
    		this.pancakeHouseMenu = pancakeHouseMenu;
    		this.dinerMenu = dinerMenu;
    	}
     
    	public void printMenu() {
    		//为每个菜单各自创建一个迭代器
    		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
    		Iterator dinerIterator = dinerMenu.createIterator();
    
    		System.out.println("MENU
    ----
    BREAKFAST");
    		//对每个迭代器调用重载printMenu(),将迭代器传入
    		printMenu(pancakeIterator);
    		System.out.println("
    LUNCH");
    		printMenu(dinerIterator);
    	}
     
    	private void printMenu(Iterator iterator) {
    		while (iterator.hasNext()) {
    			MenuItem menuItem = (MenuItem)iterator.next();
    			System.out.print(menuItem.getName() + ", ");
    			System.out.print(menuItem.getPrice() + " -- ");
    			System.out.println(menuItem.getDescription());
    		}
    	}
     
    	// other methods here
    }

    组合模式:
    //MenuComponent对每一个方法都提供了默认的实现
    public abstract class MenuComponent {
    
    	public void add(MenuComponent 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 boolean isVegetarian() {
    		throw new UnsupportedOperationException();
    	}
    
    	public abstract Iterator<MenuComponent> createIterator();
    
    	public void print() {
    		throw new UnsupportedOperationException();
    	}
    }
    
    //首先扩展MenuComponent接口,实现菜单项
    public class MenuItem extends MenuComponent {
    
    	String name;
    	String description;
    	boolean vegetarian;
    	double price;
    
    	public MenuItem(String name, String description, boolean vegetarian,
    			double price) {
    		this.name = name;
    		this.description = description;
    		this.vegetarian = vegetarian;
    		this.price = price;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public double getPrice() {
    		return price;
    	}
    
    	public boolean isVegetarian() {
    		return vegetarian;
    	}
    
    	public Iterator<MenuComponent> createIterator() {
    		return new NullIterator();
    	}
    
    	//对于菜单项来说,此方法会打印出完整的菜单项条目
    	public void print() {
    		System.out.print("  " + getName());
    		if (isVegetarian()) {
    			System.out.print("(v)");
    		}
    		System.out.println(", " + getPrice());
    		System.out.println("     -- " + getDescription());
    	}
    	// vv MenuItemCompositeV2Main
    }
    
    //实现组合菜单
    public class Menu extends MenuComponent {
    	//菜单能够有随意数目的孩子,这些孩子都必须属于MenuComponent类型
    	ArrayList<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
    	String name;
    	String description;
      
    	public Menu(String name, String description) {
    		this.name = name;
    		this.description = description;
    	}
     
    	public void add(MenuComponent menuComponent) {
    		menuComponents.add(menuComponent);
    	}
     
    	public void remove(MenuComponent menuComponent) {
    		menuComponents.remove(menuComponent);
    	}
     
    	public MenuComponent getChild(int i) {
    		return (MenuComponent)menuComponents.get(i);
    	}
     
    	public String getName() {
    		return name;
    	}
     
    	public String getDescription() {
    		return description;
    	}
    
      
    	public Iterator<MenuComponent> createIterator() {
    		return new CompositeIterator(menuComponents.iterator());
    	}
     
     
    	public void print() {
    		System.out.print("
    " + getName());
    		System.out.println(", " + getDescription());
    		System.out.println("---------------------");
    		
    		//使用迭代器,遍历全部组件
    		Iterator<MenuComponent> iterator = menuComponents.iterator();
    		while (iterator.hasNext()) {
    			MenuComponent menuComponent = 
    				iterator.next();
    			menuComponent.print();
    		}
    	}
    }
    
    
    public class Waitress {
    	MenuComponent allMenus;
    	
    	//仅仅须要将最顶层菜单交给招待即可
    	public Waitress(MenuComponent allMenus) {
    		this.allMenus = allMenus;
    	}
    
    	public void printMenu() {
    		allMenus.print();
    	}
    
    	public void printVegetarianMenu() {
    		Iterator<MenuComponent> iterator = allMenus.createIterator();
    
    		System.out.println("
    VEGETARIAN MENU
    ----");
    		while (iterator.hasNext()) {
    			MenuComponent menuComponent = iterator.next();
    			try {
    				//我们调用全部的menuComponent的isVegetarian方法。可是Menu会抛出一个异常。由于他们不支持这个操作
    				if (menuComponent.isVegetarian()) {
    					menuComponent.print();
    				}
    			} catch (UnsupportedOperationException e) {
    				//假设菜单组件不支持这个操作,我们就对这个异常置之不理。
    			}
    		}
    	}
    }
    
    package net.dp.composite.menuiterator;
    
    
    public class MenuTestDrive {
    	public static void main(String args[]) {
    
    		//创建全部菜单
    		MenuComponent pancakeHouseMenu = 
    			new Menu("PANCAKE HOUSE MENU", "Breakfast");
    		MenuComponent dinerMenu = 
    			new Menu("DINER MENU", "Lunch");
    		MenuComponent cafeMenu = 
    			new Menu("CAFE MENU", "Dinner");
    		MenuComponent dessertMenu = 
    			new Menu("DESSERT MENU", "Dessert of course!");
      
    		MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
      
    		//使用组合的add方法,将每一个菜单增加到顶层菜单中
    		allMenus.add(pancakeHouseMenu);
    		allMenus.add(dinerMenu);
    		allMenus.add(cafeMenu);
      
    		//增加各个菜单项
    		pancakeHouseMenu.add(new MenuItem(
    			"K&B's Pancake Breakfast", 
    			"Pancakes with scrambled eggs, and toast", 
    			true,
    			2.99));
    			
    		//增加很多其它的菜单项
    		
    		//一旦将整个財大层次构造万别。将它交给女招待
     		Waitress waitress = new Waitress(allMenus);
       
    		waitress.printVegetarianMenu();
     
    	}
    }


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Swoole实战之手撸HttpServer框架 16 关于服务的平滑重启与热加载与cli_set_process_title函数的使用、添加前置进程、修改代码服务器自动热更新
    Swoole实战之手撸HttpServer框架 17 里程碑 整合前置进程、热更新、Ioc容器
    axios取消请求
    echarts使用transform缩放后导致图标模糊
    vuex4的简单使用
    Vite 按需引入 Ant Design Vue 3.0
    TS声明promise返回来的数据类型
    JavaScript一种新的数据结构类型Map
    CF1453D Checkpoints(期望)
    PLOP: Learning without Forgetting for Continual Semantic Segmentation论文阅读笔记
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4850742.html
Copyright © 2020-2023  润新知