Skip to content

Commit 0707f5e

Browse files
Iterator Pattern added and Glossary Added
1 parent 3e9148c commit 0707f5e

File tree

5 files changed

+349
-1
lines changed

5 files changed

+349
-1
lines changed

content/Glossary.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
title: Glossary
3+
tags:
4+
- glossary
5+
created: 2025-10-10
6+
---
7+
### 1. Strategy Pattern:
8+
The **Strategy Pattern** is a behavioral design pattern that defines a family of algorithms or behaviors, encapsulates each one as a separate class, and makes them interchangeable. It allows an object to change its behavior at runtime by switching between different strategies, without modifying the code that uses them.
9+
### 2. Observer Pattern:
10+
The **Observer Pattern** is a behavioral design pattern that establishes a one-to-many relationship between objects. When the state of one object (called the **subject**) changes, all its dependent objects (called **observers**) are automatically notified and updated. This helps keep data consistent across different parts of an application without tightly coupling the components.
11+
### 3. Decorator Pattern:
12+
The **Decorator Pattern** is a structural design pattern that allows you to add new functionalities or responsibilities to an object dynamically without altering its existing structure or code. It wraps the original object with additional behavior, providing a flexible alternative to subclassing.
13+
### 4. Factory Method Pattern
14+
The **Factory Method Pattern** is a creational design pattern that defines an interface for creating objects but lets subclasses decide which class to instantiate. It allows a class to defer instantiation to its subclasses, promoting flexibility and loose coupling.
15+
### 5. Abstract Factory Pattern
16+
The **Abstract Factory Pattern** is a creational design pattern that provides an interface to create families of related or dependent objects without specifying their concrete classes. It helps ensure that products created together are compatible and promotes consistency across different object families.
17+
### 6. Singleton Pattern
18+
The **Singleton Pattern** is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. It’s useful when exactly one object is needed to coordinate actions across a system.
19+
### 7. Command Pattern
20+
The **Command Pattern** is a behavioral design pattern that encapsulates a request or action as an object, allowing you to parameterize, queue, or log requests, and support undoable operations. It decouples the object that invokes the action from the object that performs it.
21+
### 8. Adapter Pattern
22+
The **Adapter Pattern** is a structural design pattern that allows incompatible interfaces to work together by converting one interface into another that the client expects. It acts as a bridge between two incompatible classes.
23+
### 9. Facade Pattern
24+
The **Facade Pattern** is a structural design pattern that provides a simplified, unified interface to a complex subsystem, making it easier for clients to interact with the system without dealing with its internal complexity.
25+
### 10. Iterator Pattern
26+
The **Iterator Pattern** is a behavioral design pattern that provides a way to access elements of a collection sequentially without exposing its underlying representation, allowing uniform traversal of different collection types.
27+
28+
_more Comming soon_
55.2 KB
Loading

content/Iterator Pattern.md

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
---
2+
title: Iterator Pattern
3+
tags:
4+
- behavioral
5+
created: 2025-10-07
6+
---
7+
## Definition
8+
9+
The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
10+
11+
---
12+
## Real World Analogy
13+
14+
The **Iterator Pattern** is used to access elements from a collection of objects (like `ArrayList`, `LinkedList`, `Stack`, `Queue`, or a raw `Array`) without exposing the collection's internal structure. Without this pattern, iterating over different collection types would be tedious, often requiring you to write custom access logic (new methods or classes) for _each_ underlying collection type. The Iterator Pattern provides a unified way to access the elements of all these different collections.
15+
16+
Suppose we are at a food court, and we have various food options from different sellers. The twist is that each seller has a different way of implementing their menu internally. For instance,
17+
- Shop 1's menu is based on an `ArrayList` implementation
18+
- Shop 2 uses a `LinkedList`
19+
- Shop 3 uses a raw `Array`, and so on.
20+
21+
To display the full menu to customers, we need a way to combine and iterate over the menus from all the shopkeepers. We'll refer to the component responsible for showing the complete menu as the **Waitress**. The Waitress needs to get the menus from every shop.
22+
23+
Let's focus on two shops: a Dinner shop and a Dessert shop. The **DinnerMenu** uses an `ArrayList` implementation, while the **DessertMenu** uses a fixed-size Java array. Each shop has its own strategy for managing its menu items.
24+
25+
If the Waitress were to iterate over these menus directly, she would need to check the underlying implementation of each menu and use specific iteration logic (e.g., a `for` loop for the array, a different loop for the `ArrayList`). If any new shop arrived with a different underlying collection, we would have to entirely change the implementation of the Waitress.
26+
27+
This is where the **Iterator Pattern** provides a clean solution. Although Java already provides the `Iterator` interface within its Collections Framework (which nearly all built-in collections use), this pattern shows us how to apply this abstraction to custom collections.
28+
29+
For any new shop that comes up with its own unique menu implementation, the shopkeeper just needs to create an **Iterator** for their specific collection type to integrate with the Food Court. The Waitress then only deals with the standard `Iterator` interface. She can easily add the new menu to her list, and the Iterator handles the logic of accessing the objects, regardless of the menu's internal structure.
30+
31+
![[iterator_waitress.png]] _Diagram explaining iteration over different menus._
32+
33+
----
34+
## Design
35+
36+
```mermaid
37+
classDiagram
38+
    class MenuItem {
39+
        -String Name
40+
        -String Description
41+
        -int Price
42+
    }
43+
44+
    class Menu {
45+
        <<interface>>
46+
        +createIterator() Iterator
47+
    }
48+
49+
    class DinnerMenu {
50+
        -ArrayList~MenuItem~ menuItems
51+
        +addItem(String name, String description, int price)
52+
        +createIterator() Iterator
53+
    }
54+
55+
    class DessertMenu {
56+
        -final int SIZE
57+
        -int numberofItem
58+
        -MenuItem[] items
59+
        +addItem(String name, String description, int price)
60+
        +createIterator() Iterator
61+
    }
62+
63+
    class DessertMenuIterator {
64+
        -MenuItem[] items
65+
        -int position
66+
        +hasNext() boolean
67+
        +next() MenuItem
68+
        +remove() void
69+
    }
70+
71+
    class Waitress {
72+
        -List~Menu~ menus
73+
        +printMenu() void
74+
        -printMenu(Iterator~MenuItem~ iterator) void
75+
    }
76+
77+
    %% Relationships
78+
    Menu <|.. DinnerMenu
79+
    Menu <|.. DessertMenu
80+
    Iterator <|.. DessertMenuIterator
81+
    DessertMenu --> DessertMenuIterator : creates
82+
    DinnerMenu --> MenuItem : contains
83+
    DessertMenu --> MenuItem : contains
84+
    Waitress --> Menu : uses
85+
                 
86+
```
87+
88+
_Class Diagram for Iterator Pattern._
89+
90+
## Implementation in Java
91+
92+
To implement the Iterator Pattern, the **Waitress** will now depend on the standard Java `Iterator` interface for accessing collections of **Menus** and **MenuItems** from the various food court shops.
93+
94+
We will use standard Java `List` and `Iterator` interfaces in our implementation.
95+
96+
**MenuItem** is the base class representing a single item on the menu, holding its name, description, and price.
97+
98+
```java title="MenuItem.java"
99+
import java.util.ArrayList;
100+
import java.util.Iterator;
101+
import java.util.List;
102+
103+
class MenuItem {
104+
private String Name;
105+
private String Description;
106+
private int Price;
107+
108+
public MenuItem(String Name, String Description, int Price) {
109+
this.Description = Description;
110+
this.Price = Price;
111+
this.Name = Name;
112+
}
113+
114+
public String getDescription() {
115+
return Description;
116+
}
117+
118+
public String getName() {
119+
return Name;
120+
}
121+
122+
public int getPrice() {
123+
return Price;
124+
}
125+
}
126+
```
127+
128+
**Menu** interface defines the contract for all menu types. Any concrete menu class must implement this, ensuring it provides a `createIterator()` method to return a standard `Iterator`.
129+
130+
```java title="Menu.java"
131+
// Creating the Interface for Menu which will return the iterator
132+
interface Menu {
133+
public Iterator<MenuItem> createIterator();
134+
}
135+
```
136+
137+
This Dinner menu uses an `ArrayList` internally to store its items. Since `ArrayList` is a standard Java collection, we can simply return its built-in iterator from the `createIterator()` method.
138+
139+
```java title="DinnerMenu.java"
140+
// Creating the Menus where it depends on the ArrayList
141+
// It has the ArrayList as Implementation.
142+
class DinnerMenu implements Menu {
143+
private ArrayList<MenuItem> menuItems = new ArrayList<MenuItem>();
144+
145+
public DinnerMenu() {
146+
addItem("Paneer Masala", "Curry Paneer Masala", 123);
147+
addItem("Butter Paneer Masala", "Tadka butter Paneer Masala", 134);
148+
addItem("Tawa Paneer Masala", "Delicious Paneer in the Tawa", 178);
149+
}
150+
151+
// Returning the Java Inbuilt iterator.
152+
@Override
153+
public Iterator<MenuItem> createIterator() {
154+
return menuItems.iterator();
155+
}
156+
157+
public void addItem(String name, String description, int price) {
158+
MenuItem menuItem = new MenuItem(name, description, price);
159+
this.menuItems.add(menuItem);
160+
}
161+
}
162+
```
163+
164+
Dessert menu uses a simple fixed-size array (`MenuItem[]`) for its internal implementation. Because a raw array does not automatically provide a standard `Iterator`, we must create a custom iterator specifically for this collection type.
165+
166+
```java title="DessertMenu.java"
167+
//Creating the another menu which implements the array so for it we need to create our custom iterator
168+
class DessertMenu implements Menu {
169+
private final int SIZE = 3;
170+
private int numberofItem = 0;
171+
private MenuItem[] items = new MenuItem[SIZE];
172+
173+
public DessertMenu() {
174+
addItem("Gulab Jamun", "Sweet and Juicy ", 89);
175+
addItem("Rasmalai", "Pure Milk Rasmalai", 350);
176+
addItem("Rabdi", "Pure and Fresh Milk Rabdi", 230);
177+
}
178+
179+
public void addItem(String name, String description, int price) {
180+
MenuItem menuItem = new MenuItem(name, description, price);
181+
if (numberofItem < SIZE) {
182+
items[numberofItem++] = menuItem;
183+
} else {
184+
System.err.println("Number of Items Reached");
185+
}
186+
}
187+
188+
// For this array-based menu, we return an instance of our custom iterator.
189+
@Override
190+
public Iterator<MenuItem> createIterator() {
191+
return new DessertMenuIterator(this.items);
192+
}
193+
}
194+
```
195+
196+
**DessertMenuIterator** is the **custom iterator** created specifically to traverse the raw `MenuItem[]` array used by the `DessertMenu`. It implements the standard `Iterator<MenuItem>` interface, providing uniform access methods like `hasNext()` and `next()`.
197+
198+
```java title="DessertMenuIterator.java"
199+
// Creating our custom iterator using the java Iterator
200+
class DessertMenuIterator implements Iterator<MenuItem> {
201+
private MenuItem[] items;
202+
private int position = 0;
203+
204+
public DessertMenuIterator(MenuItem[] menuItems) {
205+
this.items = menuItems;
206+
}
207+
208+
@Override
209+
public boolean hasNext() {
210+
// Check if the current position is within the bounds of the array and the item is not null
211+
return position < items.length && items[position] != null;
212+
}
213+
214+
@Override
215+
public MenuItem next() {
216+
// Return the current item and advance the position
217+
return this.items[position++];
218+
}
219+
220+
@Override
221+
public void remove() {
222+
throw new UnsupportedOperationException("This method is not implemented for the DessertMenuIterator");
223+
}
224+
}
225+
```
226+
227+
The `Waitress` class is the **client** that depends only on the high-level `Menu` interface and the standard `Iterator` interface. This allows her to work with any menu implementation without knowing or caring if the menu uses an `ArrayList`, a raw `Array`, or any other collection internally.
228+
229+
```java title="Waitress.java"
230+
// Implementing the Waitress Code
231+
class Waitress {
232+
private List<Menu> menus;
233+
234+
public Waitress(List<Menu> menu) {
235+
this.menus = menu;
236+
}
237+
238+
public void printMenu() {
239+
// Loop through all the menus provided
240+
for (Menu currentmenu : menus) {
241+
System.out.println("\n--- " + currentmenu.getClass().getSimpleName() + " Menu ---");
242+
// Ask the menu to create its appropriate iterator
243+
Iterator<MenuItem> iterator = currentmenu.createIterator();
244+
// Pass the standard iterator to the printing method
245+
printMenu(iterator);
246+
}
247+
}
248+
249+
// Printing all the Menu items present in the Menus using the Iterator
250+
private void printMenu(Iterator<MenuItem> iterator) {
251+
// The iteration logic is now uniform regardless of the underlying collection type
252+
while (iterator.hasNext()) {
253+
MenuItem menuItem = iterator.next();
254+
System.out.print(menuItem.getName() + ", ");
255+
System.out.print("$" + menuItem.getPrice() + " --- ");
256+
System.out.println(menuItem.getDescription());
257+
}
258+
}
259+
}
260+
```
261+
262+
This is the main class where we demonstrate the pattern. We create instances of different menu types and pass them to the `Waitress`. The Waitress successfully prints both menus using a single, unified iteration logic defined by the `Iterator` interface.
263+
264+
```java title="IteratorPatternDemo.java"
265+
public class IteratorPatternDemo {
266+
public static void main(String[] args) {
267+
// Initiating the menu classes
268+
Menu desertMenu = new DessertMenu();
269+
Menu dinnerMenu = new DinnerMenu();
270+
271+
// The Waitress accepts a list of Menu objects, regardless of their internal implementation.
272+
Waitress waitress = new Waitress(new ArrayList<Menu>() {
273+
{
274+
add(desertMenu);
275+
add(dinnerMenu);
276+
}
277+
});
278+
279+
waitress.printMenu();
280+
}
281+
}
282+
```
283+
284+
Now, whenever any new Menu Arrives, the developer only needs to create the Menu using the `Menu` interface and implement its specific `createIterator()` method. The new Menu is then simply added to the `ArrayList` of the Waitress, and the existing iteration logic remains unchanged. This is the power of the **Iterator Pattern**: decoupling the client (Waitress) from the collection structure (Menu implementation).
285+
286+
**Output:**
287+
```txt
288+
DessertMenu ==
289+
Gulab Jamun, 89 --- Sweet and Juicy
290+
Rasmalai, 350 --- Pure Milk Rasmalai
291+
Rabdi, 230 --- Pure and Fresh Milk Rabdi
292+
293+
DinnerMenu ==
294+
Paneer Masala, 123 --- Curry Paneer Masala
295+
Butter Paneer Masala, 134 --- Tadka butter Paneer Masala
296+
Tawa Paneer Masala, 178 --- Delicious Paneer in the Tawa
297+
```
298+
These is the output for the `IteratorpatternDemo`class.
299+
300+
---
301+
## Real World Example
302+
303+
The Iterator Pattern is used in almost every application where element iteration is required. Key examples include:
304+
- **Java Collections Framework:** All core collection classes (like `ArrayList`, `HashSet`, `HashMap` keys/values) implement the `Iterable` interface, which provides the `iterator()` method.
305+
- **JDBC:** Iterators are implicitly used when reading result sets from a `SELECT` query.
306+
- **I/O buffers:** Iteration is used when sequentially reading data from files or streams.
307+
308+
----
309+
## Design Principles:
310+
311+
- **Encapsulate What Varies** - Identify the parts of the code that are going to change and encapsulate them into separate class just like the Strategy Pattern.
312+
- **Favor Composition Over Inheritance** - Instead of using inheritance on extending functionality, rather use composition by delegating behavior to other objects.
313+
- **Program to Interface not Implementations** - Write code that depends on Abstractions or Interfaces rather than Concrete Classes.
314+
- **Strive for Loosely coupled design between objects that interact** - When implementing a class, avoid tightly coupled classes. Instead, use loosely coupled objects by leveraging abstractions and interfaces. This approach ensures that the class does not heavily depend on other classes.
315+
- **Classes Should be Open for Extension But closed for Modification** - Design your classes so you can extend their behavior without altering their existing, stable code.
316+
- **Depend on Abstractions, Do not depend on concrete class** - Rely on interfaces or abstract types instead of concrete classes so you can swap implementations without altering client code.
317+
- **Talk Only To Your Friends** - An object may only call methods on itself, its direct components, parameters passed in, or objects it creates.
318+
- **Don't call us, we'll call you** - This means the framework controls the flow of execution, not the user’s code (Inversion of Control).
319+
- **A class should have only one reason to change** - This emphasizes the Single Responsibility Principle, ensuring each class focuses on just one functionality.

content/Observer Pattern.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ created: 2025-02-18
66
---
77
## Definition
88

9-
It Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Just like the Subscription, as long as you take the subscription you will get the updates, when you invoke the Subscription you will stop getting the updates or say the services.
9+
It Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Just like the Subscription, as long as you take the subscription you will get the updates, when you revoke the Subscription you will stop getting the updates or say the services.
1010

1111
---
1212
## Real World Analogy

content/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ Consider an `SQLManager` class that performs CRUD operations. It has an `ILogger
127127
8. [[Adapter Pattern]]
128128
9. [[Facade Pattern]]
129129
10. [[Quiz-1]]
130+
11. [[Iterator Pattern]]
130131

131132
---
132133
> [!Note]

0 commit comments

Comments
 (0)