Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Luca Vigan
Dipartimento di Informatica Universit di Verona
1 / 37
A Diner and a Pancake House merge, but there is a slight problem... They want to use the Pancake Houses menu as the breakfast menu and Diners menu as the lunch menu, but...
Pancake House uses an ArrayList to hold its menu, Diner uses an Array to hold its menu, and neither one of them is willing to change its implementation... they just have too much code written that depends on them.
2 / 37
Now lets take a look at what Pancake House and Diner are arguing about. They both have lots of time and code invested in the way they store their menu items in a menu, and lots of other code that depends on it. Implementation of the Pancake House Menu...
3 / 37
continue ...
Luca Vigan (Universit di Verona) The Iterator Pattern Lab. Ing. del SW, 27.05.2011 4 / 37
5 / 37
continue ...
Luca Vigan (Universit di Verona) The Iterator Pattern Lab. Ing. del SW, 27.05.2011 6 / 37
To see why having two different menu representations complicates things, lets try implementing a client that uses the two menus. Imagine you have been hired by the new company formed by the merger of the Diner and the Pancake House to create a Java-enable waitress. The specication of waitress species that she can print a custom menu for customers on demand, and even tell you if a menu item is vegetarian without having to ask the cook. Lets check out the specication, and then step through what it might take to implement the waitress.
8 / 37
9 / 37
Lets start by stepping through how wed implement the printMenu() method: To print all the items on each menu, youll need to call the getMenuItem() method on the pancakeHouseMenu and the DinerMenu to retrieve their respective menu items. Note that each returns a different type:
PancakeHouseMenu pancakeHouseMenu=new PancakeHouseMenu ( ) ; A r r a y L i s t b r e a k f a s t I t e m s =pancakeHouseMenu . getMenuItems ( ) ; DinerMenu DinerMenu = new DinerMenu ( ) ; Menultem [ ] l u n c h l t e m s = DinerMenu . getMenuItems ( ) ;
10 / 37
Menultem menultem = ( Menultem ) b r e a k f a s t l t e m s . g e t ( i ) ; System . o u t . p r i n t ( menuItem . getName { ) + " " ); System . o u t . p r i n t I n ( menultem . g e t P r i c e ( ) + " " ); System . o u t . p r i n t I n ( menultem . g e t D e s c r i p t i o n ( ) ) ; } for ( int i = 0; i < l u n c h l t e m s . l e n g t h ; i ++) {
Menultem menultem = l u n c h l t e m s [ i ] ; System . o u t . p r i n t ( menultem . getName ( ) + " " ); System . o u t . p r i n t I n ( menultem . g e t P r i c e ( ) + " " ); System . o u t . p r i n t I n ( menultem . g e t D e s c r i p t i o n ( ) ) ; }
11 / 37
Implementing every other method in the Waitress is going to be a variations of this theme. Were always going to need to get both menus and use two loops to iterate through their items. If another restaurant with a different implementation is acquired then well have three loops.
12 / 37
13 / 37
14 / 37
15 / 37
16 / 37
17 / 37
18 / 37
19 / 37
20 / 37
21 / 37
22 / 37
Now we need to integrate the iterator code into the Waitress. We should be able to get rid of some of the redundancy in the process. Integration is pretty straightforward:
1 2
rst we create a printMenu() method that takes an Iterator; then we use the createlterator() method on each menu to retrieve the Iterator and pass it to the new method.
23 / 37
24 / 37
Its time to put everything to a test. Lets write some test drive code and see how the Waitress works...
public class MenuTestDrive { public s t a t i c void main ( S t r i n g [ ] args ) { Menu pm = new PancakeHouseMenu ( ) ; Menu dm = new DinerMenu ( ) ; W a i t r e s s w = new W a i t r e s s (pm,dm ) ; w . printMenu ( ) ; } }
25 / 37
26 / 37
Not only does java.util have its own Iterator interface, but ArrayList has an iterator() method that returns an iterator.
In other words, we never needed to implement our own iterator for ArrayList.
However, well still need our implementation for the DinerMenu because it relies on an Array, which doesnt support the iterator() method (or any other way to create an array iterator).
Luca Vigan (Universit di Verona) The Iterator Pattern Lab. Ing. del SW, 27.05.2011 28 / 37
We just delete the PancakeHouseMenuIterator class add an import java.util.Iterator to the top of PancakeHouseMenu and change one line of the PancakeHouseMenu.
29 / 37
Now we need to make the changes to allow the DinerMenu to work with java.util.Iterator:
30 / 37
31 / 37
Now we need to add an implements Menu to both the PancakeHouseMenu and the DinerMenu class denitions and update the Waitress:
32 / 37
To solve the problem of the Waitress depending on the implementation of the MenuItems:
The new Menu interface has one method, createIterator(), that is implemented by PancakeHouseMenu and DinerMenu. Each menu class assumes the responsibility of creating a concrete Iterator that is appropriate for its internal implementation of the menu items.
Luca Vigan (Universit di Verona) The Iterator Pattern Lab. Ing. del SW, 27.05.2011 33 / 37
34 / 37
37 / 37