- 浏览: 1028229 次
-
文章分类
最新评论
-
l67721363:
感谢分享,要是有各个函数性能比较就好了。
SQL优化 数据库优化 -
hanmiao:
此图片来自QQ空间,未经允许不可引用。
Hacking QQ空间
设计模式笔记09-迭代器与组合模式
设计模式笔记09-迭代器与组合模式
1 引言
有许多方法可以把对象堆起来成为一个集合(collection)。你可以把他们放进数组、堆栈、或者是散列表中,这是你的自由。每一种都有它自己的优点和适合的使用时机,但总是有一个时候,你的客户想要遍历这些对象,而当他这么做的时候,你打算让客户看到你的实现吗?我们当然希望不要!这太不专业可。没关系,不要为你的工作担心,你将在本章中学习如何能让客户遍历你的对象而又无法窥视你存储对象的方式;也将学习如何创建一些对象集合(super collection),能够一口气就跳过某些让人望而生畏的数据结构。你还将学到一些关于对象职责的知识。
2 正文
2.1 对象村餐厅和对象村煎饼屋合并了
这真是个好消息,现在我们可以在同一个地方想用两种食品了。但是,好像有点麻烦。煎饼屋的菜单使用数组存储,而餐厅的菜单使用ArrayList存储。至少是两个餐厅都统一按照下面的代码来实现菜单项(单独的菜品)。
菜单项实现:
public class MenuItem { String name; String description; boolean vegetarian; double price; /* * 菜单项包含了名称、描述、是否为素食、价格 * 将这些值传入构造器来初始化这个菜单项 * * 下面的getter方法可以获取菜单项的各个字段 */ 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 class PancakeHouseMenu implements Menu { ArrayList menuItems; /* * 这是煎饼屋的实现 * 使用一个ArrayList存储他的菜单项 * 在菜单的构造器中,每一个菜单项都会被加入到ArrayList中 * * 要加入一个菜单项,煎饼屋的做法是:创建一个新的菜单项对象,传入每一个变量, * 然后将它加入到此ArrayList中 */ public PancakeHouseMenu() { menuItems = new ArrayList(); addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99); addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99); addItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49); addItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59); } public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); menuItems.add(menuItem); } public ArrayList getMenuItems() { return menuItems; } }
餐厅的菜单实现
public class DinerMenu implements Menu { static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; /* * 1 餐厅使用的是数组来存储菜单项,所以可以控制菜单的长度,并且在去除菜单项的时候,不需要转类型 * 2 和煎饼屋一样,餐厅也是使用addItem()方法在构造器中创建菜单项 * 3 addItem()方法需要拿所有必要的参数来创建一个菜单项,并实例化它。这个方法也会检查数组是否 * 超过了数组的最大长度 */ 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 MenuItem[] getMenuItems() { return menuItems; } }
以上实现的缺点:
1、我们是针对PancakeHouseMenu和DinnerMenu的具体实现编码,不是针对接口。
2、如果我们决定从DinnerMenu切换到另一种菜单,此菜单的项是用HashTable来存放的,我们会因此需要修改女招待中的许多代码。
3、女招待需要知道每个菜单如何表达内部的菜单项项集合,这违反了封装。
4、我们有重复的代码,printMenu()方法需要两个循环,来遍历两种不同的菜单。如果我们加上第三种菜单,我们就需要三个循环。
2.2 会见迭代器模式
关于迭代器模式,你所需要知道的第一件事情,就是它依赖于一个名为迭代器的接口。
一个迭代器包含两个接口:hasNext()方法告诉我们是否在这个聚合中还有更多的元素,next()方法返回这个聚合中的下一个对象。
现在我们需要为餐厅菜单实现一个具体的迭代器
public class DinerMenuIterator implements Iterator { MenuItem[] items; int position = 0; /* * 实现迭代器接口 * 1 position记录当前数组遍历的位置 * 2 构造器需要被传入一个菜单项的数组当做参数 * 3 next()方法返回数组内的下一个元素,并递增其位置 * 4 hasNext()方法会检查我们是否已经取得数组内所有的元素。如果还有元素待遍历,就返回true * 5 因为使用的固定长度的数组,所以要检查数组长度是否超过了最大长度和是否为null */ 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 Waitress { Menu pancakeHouseMenu; Menu dinerMenu; public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) { this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; } public void printMenu() { Iterator pancakeIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); System.out.println("MENU\n----\nBREAKFAST"); printMenu(pancakeIterator); System.out.println("\nLUNCH"); 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()); } } }
在清理一切之前,让我们从整体上看下目前的设计。
1、两个菜单实现相同的接口。
2、煎饼屋菜单和餐厅菜单都实现了新的createIterator()方法,它们负责为各自的菜单项创建迭代器。
3、迭代器让女招待能够从具体类的实现中解耦。她不需要知道菜单是使用数组、ArrayList,还是便利贴来实现。她只关心她能够取得的迭代器。
2.3 定义迭代器模式
迭代器模式:提供一种方法书序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
这很有意义:这个模式给你提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不知道内部是如何表示的。
另一个队你的设计造成重要影响的:迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所应该专注的事情上面(管理对象集合),而不必去理会遍历的事情。
单一责任:一个类应该只有一个引起变化的原因。
类的每个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变的区域。
这个原则告诉我们尽量让每一个类保持单一责任。
要如何解决呢?这听起来很容易,但其实做起来并不简单:区分设计中的责任,是最困难的事情之一。我们的大脑很习惯看着一大群的行为,然后将他们集中在一起。我们的大脑很习惯看着一大群的行为,然后将它们集中在一起,尽管他们可能属于两个或者多个不同的责任。
想要成功的唯一方法,就是努力不懈地检查你的设计,随着系统的成长,随时观察有没有迹象显示某个类改变的原因超出一个。
2.4 迭代器与集合
我们所使用的这些类都属于Java Collection Framework的一部分。这里所谓的Framework指的是一群类和接口,其中包括了ArrayList、Vector、LinkedList、Stack和PriorityQueue。这些类都实现了Java.util.Collection接口。这个接口包含了很多有用的方法,可以操纵一群对象。
Java 5的迭代器和集合
Java 5包含一种新形势的for语句,成为for/in。这可以让你在一个集合或者一个数组中遍历,而且不需要显式创建迭代器。想使用for/in,语法是这样的
for (Object obj: collection)
{
//动作
}
2.5 初始组合模式
正当我们以为这一切很完美的时候,现在他们希望能够加上一份餐后甜点的“子菜单”。
如果我们能让甜点菜单编程餐厅菜单集合的一个元素,那该有多好。但是根据现在的实现,根据做不到。
所以在我们的新设计中,真正需要些什么呢?
1 我们需要某种树形结构,可以容纳菜单、子菜单和菜单项。
2 我们需要确定能够在每个菜单的各个项之间游走,而且至少要像现在用迭代器一样方便。
3 我们也需要能够更有弹性地再菜单项之间游走。比方说,可能只需要遍历甜点菜单,或者可以遍历餐厅的整个菜单(包括甜点菜单在内)。
组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。
使用组合机构,我们能把相同的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
2.6 利用组合设计菜单
我们要如何在菜单上应用组合模式呢?一开始,我们需要创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。换句话说,我们可以针对菜单或者菜单项调用相同的方法。
实现菜单组件,所有的组件都必须实现MenuComponent接口;然而,叶节点和组合节点的角色不同,所以有些方法可能并不适合某种节点。面对这种情况,有时候,你最好直接抛出运行时异常。
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 boolean isVegetarian() { throw new UnsupportedOperationException(); } public void print() { throw new UnsupportedOperationException(); } }
实现菜单项
public class MenuItem extends MenuComponent { String name; String description; boolean vegetarian; double price; /* * 1 首先我们要扩展MenuComponent接口 * 2 其他和之前的类定义没有太大区别,增加了toString()方法 */ 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 void print() { System.out.print(" " + getName()); if (isVegetarian()) { System.out.print("(v)"); } System.out.println(", " + getPrice()); System.out.println(" -- " + getDescription()); } }
实现组合菜单
public class Menu extends MenuComponent { ArrayList menuComponents = new ArrayList(); String name; String description; /* * 1 菜单和菜单项一样,都是MenuComponent * 2 菜单可以有任意数目的子节点,这些子节点都必须属于MenuComponent类型,使用内部ArrayList记录它们 * 3 我们再这里将菜单项和其他菜单加入到菜单中。因为菜单和菜单项都是MenuComponent,所以我们只需要一个方法就可以两者兼顾 * 4 同样的道理,我们也可以删除或取得某个MenuComponent */ 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 void print() { System.out.print("\n" + getName()); System.out.println(", " + getDescription()); System.out.println("---------------------"); Iterator iterator = menuComponents.iterator(); while (iterator.hasNext()) { MenuComponent menuComponent = (MenuComponent)iterator.next(); menuComponent.print(); } } }
编写测试程序
public class MenuTestDrive { public static void main(String args[]) { /* * 1 先创建所有的菜单对象 * 2 我们需要一个最顶层的菜单,将它称为allMenus * 3 我们使用组合的add()方法,将每个菜单都加入到顶层戴丹allMenu()中 * 4 现在我们需要加上所有的菜单项 * 5 然后我们也在菜单中加入另一个菜单 * 6 一旦我们将珍格格菜单层次构造完毕,把它整个交给女招待,你会发现,女招待要将整份菜单打印出来,简直易如反掌 */ 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 coffeeMenu = new Menu("COFFEE MENU", "Stuff to go with your afternoon coffee"); MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined"); 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)); pancakeHouseMenu.add(new MenuItem( "Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99)); pancakeHouseMenu.add(new MenuItem( "Blueberry Pancakes", "Pancakes made with fresh blueberries, and blueberry syrup", true, 3.49)); pancakeHouseMenu.add(new MenuItem( "Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59)); dinerMenu.add(new MenuItem( "Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99)); dinerMenu.add(new MenuItem( "BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99)); dinerMenu.add(new MenuItem( "Soup of the day", "A bowl of the soup of the day, with a side of potato salad", false, 3.29)); dinerMenu.add(new MenuItem( "Hotdog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05)); dinerMenu.add(new MenuItem( "Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99)); dinerMenu.add(new MenuItem( "Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89)); dinerMenu.add(dessertMenu); dessertMenu.add(new MenuItem( "Apple Pie", "Apple pie with a flakey crust, topped with vanilla icecream", true, 1.59)); dessertMenu.add(new MenuItem( "Cheesecake", "Creamy New York cheesecake, with a chocolate graham crust", true, 1.99)); dessertMenu.add(new MenuItem( "Sorbet", "A scoop of raspberry and a scoop of lime", true, 1.89)); cafeMenu.add(new MenuItem( "Veggie Burger and Air Fries", "Veggie burger on a whole wheat bun, lettuce, tomato, and fries", true, 3.99)); cafeMenu.add(new MenuItem( "Soup of the day", "A cup of the soup of the day, with a side salad", false, 3.69)); cafeMenu.add(new MenuItem( "Burrito", "A large burrito, with whole pinto beans, salsa, guacamole", true, 4.29)); cafeMenu.add(coffeeMenu); coffeeMenu.add(new MenuItem( "Coffee Cake", "Crumbly cake topped with cinnamon and walnuts", true, 1.59)); coffeeMenu.add(new MenuItem( "Bagel", "Flavors include sesame, poppyseed, cinnamon raisin, pumpkin", false, 0.69)); coffeeMenu.add(new MenuItem( "Biscotti", "Three almond or hazelnut biscotti cookies", true, 0.89)); Waitress waitress = new Waitress(allMenus); waitress.printMenu(); } }
关于组合模式的小疑问。
组合模式以单一责任设计原则获取透明性(transparency)。什么是透明性?通过让组件和接口同时包含一些管理子节点和叶节点的操作,客户就可以将组合和叶节点一视同仁。也就是说,一个元素究竟是组合还是叶节点,对客户是透明的。
所以,回到上面的问题,这是一个很典型的折中案例。尽管我们收到设计原则的知道,但是,我们总是需要观察某原则对我们设计所造成的影响。有时候,我们会故意做一些看似违反原则的事情。
2.7 组合迭代器
1 我们在MenuComponent中加入一个createIterator()方法,这意味着每个菜单和菜单项都必须实现这个方法,也意味着,对一个组合调用CreateIterator()方法,将会应用于该组合的所有孩子。
2 现在我们需要在菜单和菜单项中实现这个方法。
这个CompositeIterator是一个不可小觑的迭代器。它的工作室遍历组件内的菜单项,而且确保所有的子菜单都被包括进来。
注意:这里使用的递归,跟我默念“递归是我的朋友,递归是我的朋友。。。。”
public class CompositeIterator implements Iterator { Stack stack = new Stack(); public CompositeIterator(Iterator iterator) { stack.push(iterator); } /* * (non-Javadoc) * @see java.util.Iterator#next() * 1 当客户想要取得下一个元素的时候,我们先调用hasNext()来确定是否还有下一个 * 2 如果还有下一个元素,我们就从堆栈中取出目前的迭代器,然后取得它的下一个元素 * 3 如果元素时一个菜单那,我们有了另一个需要被包含进遍历中的组合,所以我们将它丢进堆栈中。不管是不是菜单那,我们都返回该组件。 */ public Object next() { if (hasNext()) { Iterator iterator = (Iterator) stack.peek(); MenuComponent component = (MenuComponent) iterator.next(); if (component instanceof Menu) { stack.push(component.createIterator()); } return component; } else { return null; } } /* * (non-Javadoc) * @see java.util.Iterator#hasNext() * 1 想要知道是否还有下一个元素,我们检查堆栈是否被清空;如果已经空了,就表示没有下一个元素了 * 2 否则,我们就从堆栈的顶层中取出迭代器,看看是否还有下一个元素,如果没有元素,我们将它弹出堆栈,然后递归地调用hasNext() * 3 否则,表示还有下一个元素,我们返回true */ public boolean hasNext() { if (stack.empty()) { return false; } else { Iterator iterator = (Iterator) stack.peek(); if (!iterator.hasNext()) { stack.pop(); return hasNext(); } else { return true; } } } public void remove() { throw new UnsupportedOperationException(); } }
3 本章小结
好长的一章,代码片也不少,好在终于到头了。学习过程中我们经常会遇到这种相对较长的学习周期,这时候可以分解为多个步骤来完成,可以实时记录自己的进度,而不是简单的未完成/已完成,可以有一定的激励作用噢。
回到这章设计模式来,迭代器大家想必不会陌生,这边自定义了迭代器接口为的就是让我们明白迭代器的工作原理。组合模式结合递归算法,这个在处理树形结构时绝对是利器。之前在写一个小工具时,也遇到过类似的问题,当时还不知道有此等利器,完全凭自己的想法把功能实现了,回头看看有没有优化的可能。需求很简单,把Excel中的记录按照树形结构输出成xml文件,有兴趣的同学可以看下我之前的博客(http://blog.csdn.net/adoaiwen1314/article/details/17075491),欢迎提出用组合迭代器模式设计的代码。
相关推荐
迭代器模式是一种设计模式,它在软件开发中用于顺序访问聚合对象(如列表、集合等)的元素,而无需暴露其内部结构。这种模式允许在不同的聚合对象间使用相同的遍历逻辑,增强了代码的可复用性和灵活性。 在C#中,...
这个“Java版设计模式学习笔记”涵盖了多种设计模式,旨在帮助开发者更好地理解和应用这些模式。让我们深入探讨一下其中可能包含的关键知识点。 一、单例模式 单例模式确保一个类只有一个实例,并提供一个全局访问...
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决问题的...设计模式笔记中的内容应该涵盖了以上所述的各种模式,通过深入学习和实践,你可以将这些模式应用到实际项目中,提升自己的编程技能和设计能力。
在《23个设计模式图解--学习笔记》中,我们探讨了这些模式,以便于理解和应用到实际开发中。以下是这23个设计模式的详细说明: 1. **工厂方法**(Factory Method):定义一个用于创建对象的接口,让子类决定实例化...
- 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):定义一个中介对象来简化原本复杂的对象交互。 - 观察者模式(Observer):定义对象之间的一...
这份"根据《JAVA与设计模式》整理的笔记及示例代码"涵盖了Java语言和设计模式的核心概念,旨在帮助开发者理解和应用这些模式。 一、设计模式的基本概念 设计模式是对在特定情境下软件设计问题的解决方案的一种描述...
结构型模式则涉及如何组合类和对象,包括适配器、桥接、组合、装饰器、外观、享元和迭代器模式,它们提供了增强结构和解耦的手段。行为型模式专注于类或对象间的交互和职责分配,如模板方法、命令、解释器、责任链、...
设计模式Golang实现《研磨设计模式》读书笔记Go语言设计模式Go语言设计模式的实例代码创建模式工厂简单模式(Simple Factory)工厂方法模式(工厂方法)抽象工厂模式(Abstract Factory)创建者模式(Builder)原型...
设计模式是软件开发中的一种重要概念,它是经过时间验证、广泛认可的代码设计经验的总结。设计模式可以被归类为创建型、结构型和行为型三类,每类包含若干种模式,如创建型中的工厂方法模式、抽象工厂模式、单例模式...
设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...
本资料“图解Java设计模式笔记总结word版本”聚焦于通过图文并茂的方式,深入浅出地解析各种设计模式。以下是基于这个主题的详细知识点讲解: 1. **设计模式的分类** - **创建型模式**:如单例(Singleton)、工厂...
5. **设计模式的使用场景与优缺点** 设计模式并非银弹,每个模式都有其适用的场景和局限性。正确使用设计模式可以提高代码的可读性、可维护性和复用性,但过度使用或不恰当的使用可能会导致设计过于复杂,增加学习...
这个压缩包中的“设计模式笔记”涵盖了所有23种GOF(GoF,Gamma, Helm, Johnson, Vlissides四位作者)经典设计模式,这些模式是面向对象设计的核心组成部分,对于提升代码的可读性、可维护性和可扩展性具有重要意义...
本资源“23种设计模式的解析与Cpp实现”详细介绍了这一主题,包括每种设计模式的基本概念、作用、实现方式以及如何在实际项目中应用。 1. **创建型模式**(Creational Patterns):这类模式主要关注对象的创建,...
行为型模式则关注对象之间的交互和责任分配,如策略模式、模板方法模式、观察者模式、访问者模式、命令模式、迭代器模式、职责链模式、解释器模式和备忘录模式等。 C++作为一种静态类型、编译式、面向对象的语言,...
根据给定的信息“图解设计模式,结城浩著学习笔记”,我们可以推断出这份文档主要涉及了设计模式的学习和理解。《图解设计模式》是一本由日本著名程序员结城浩撰写的书籍,该书以图形化的方式深入浅出地讲解了软件...
这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,以及它们在Java编程中的应用。 1. **单例模式**:确保一个类只有一个实例,并...
设计模式如抽象工厂模式、工厂方法模式、策略模式、观察者模式、装饰者模式、桥接模式、单例模式、命令模式、适配器模式、外观模式、模板方法模式、迭代器、状态模式、组合模式、代理模式、生成器模式、职责链模式、...
### 个人笔记--JAVA基础 #### 一、初识Java **1.1. Java语言是什么** Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年发布。它被设计为简单、面向对象、分布式、解释型、健壮、安全、与体系结构...