iterator
This commit is contained in:
parent
afb0c148a1
commit
935f9c7563
|
@ -10,6 +10,7 @@
|
|||
2. [Наблюдатель](observer/)
|
||||
3. [Команда](command/)
|
||||
4. [Шаблонный метод](templatemethod/)
|
||||
5. [Итератор](iterator/)
|
||||
|
||||
### Структурные
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Итератор
|
||||
|
||||
Поведенческий паттерн проектирования, который даёт возможность последовательно обходить элементы составных объектов, не раскрывая их внутреннего представления.
|
||||
|
||||
Паттерн **Итератор** предоставляет механизм последовательного перебора элементов коллекции без раскрытия ее внутреннего представления.
|
||||
|
||||
## Принципы
|
||||
|
||||
- Класс должен иметь только одну причину для изменения
|
||||
|
||||
Поручая классу не только его непосредственную задачу (управление коллекцией объектов), но и дополнительные задачи (перебор), создаются две возможные причины для изменения. Теперь измениться может как внутренняя реализация коллекции, так и механизм перебора.
|
||||
|
||||
### Связность
|
||||
|
||||
![coupling_cohesion.png](coupling_cohesion.png)
|
||||
|
||||
Модуль или класс обладает ***высокой связностью*** (*high cohesion*), если он спроектирован для выполнения группы взаимосвязанных функций. Классы с ***низкой связностью*** (*low coupling*) проектируются на основе набора разрозненных функций.
|
||||
|
||||
Классы, соответствующие принципу, обычно обладают высокой связностью, и более просты в сопровождении, чем классы с многими обязанностями и низкой связностью.
|
||||
|
||||
## Схемы
|
||||
|
||||
![scheme-1](scheme-1.png)
|
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
Binary file not shown.
After Width: | Height: | Size: 305 KiB |
|
@ -0,0 +1,10 @@
|
|||
module app;
|
||||
|
||||
import dinermenu, menu, waitress;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto waitress = new Waitress(new DinerMenu());
|
||||
waitress.printMenu();
|
||||
waitress.printVegetarianMenu();
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
module dinermenu;
|
||||
|
||||
import menu, menuitem, iterator, dinermenuiterator;
|
||||
import std.stdio : writeln;
|
||||
|
||||
class DinerMenu : Menu
|
||||
{
|
||||
static const int MAX_ITEMS = 6;
|
||||
private int numberOfItems = 0;
|
||||
private MenuItem[] menuItems;
|
||||
|
||||
this()
|
||||
{
|
||||
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 sauerkraut, 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);
|
||||
}
|
||||
|
||||
void addItem(string name, string description, bool vegetarian, double price)
|
||||
{
|
||||
if (numberOfItems >= MAX_ITEMS)
|
||||
{
|
||||
writeln("Sorry, menu is full! Can't add item to menu");
|
||||
}
|
||||
else
|
||||
{
|
||||
menuItems[numberOfItems++] = new MenuItem(name, description, vegetarian, price);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem[] getMenuItems()
|
||||
{
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
override Iterator createIterator()
|
||||
{
|
||||
return new DinerMenuIterator(menuItems);
|
||||
}
|
||||
|
||||
override string toString() const @safe pure nothrow
|
||||
{
|
||||
return "Diner Menu";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
module dinermenuiterator;
|
||||
|
||||
import iterator, menuitem;
|
||||
|
||||
class DinerMenuIterator : Iterator
|
||||
{
|
||||
private MenuItem[] items;
|
||||
private int position;
|
||||
|
||||
this(MenuItem[] items)
|
||||
{
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
override MenuItem next()
|
||||
{
|
||||
return items[position++];
|
||||
}
|
||||
|
||||
override bool hasNext()
|
||||
{
|
||||
return items.length > position;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module iterator;
|
||||
|
||||
import menuitem;
|
||||
|
||||
interface Iterator
|
||||
{
|
||||
bool hasNext();
|
||||
MenuItem next();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
module menu;
|
||||
|
||||
import iterator;
|
||||
|
||||
interface Menu
|
||||
{
|
||||
Iterator createIterator();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
module menuitem;
|
||||
|
||||
import std.conv : to;
|
||||
|
||||
class MenuItem
|
||||
{
|
||||
private string name;
|
||||
private string description;
|
||||
private bool vegetarian;
|
||||
private double price;
|
||||
|
||||
this(string name, string description, bool vegetarian, double price)
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.vegetarian = vegetarian;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
string getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
double getPrice()
|
||||
{
|
||||
return price;
|
||||
}
|
||||
|
||||
bool isVegetarian()
|
||||
{
|
||||
return vegetarian;
|
||||
}
|
||||
|
||||
override string toString() const
|
||||
{
|
||||
return (name ~ ", $" ~ price.to!string ~ "\n " ~ description);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
module waitress;
|
||||
|
||||
import menu, iterator, menuitem;
|
||||
import std.stdio : writeln, write;
|
||||
|
||||
class Waitress
|
||||
{
|
||||
private Menu dinerMenu;
|
||||
|
||||
this(Menu dinerMenu)
|
||||
{
|
||||
this.dinerMenu = dinerMenu;
|
||||
}
|
||||
|
||||
void printMenu()
|
||||
{
|
||||
writeln("MENU\n----\nLUNCH");
|
||||
printMenu(dinerMenu.createIterator());
|
||||
}
|
||||
|
||||
private void printMenu(Iterator iterator)
|
||||
{
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
MenuItem menuItem = iterator.next();
|
||||
write(menuItem.getName(), ", ");
|
||||
write(menuItem.getPrice(), " -- ");
|
||||
writeln(menuItem.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
void printVegetarianMenu()
|
||||
{
|
||||
writeln("MENU\n----\nVEGETARIAN");
|
||||
printVegetarianMenu(dinerMenu.createIterator());
|
||||
}
|
||||
|
||||
// bool isItemVegetarian(string name)
|
||||
// {
|
||||
// Iterator dinnerIterator = dinerMenu.createIterator();
|
||||
// if (isVegetarian(name, dinnerIterator))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
private void printVegetarianMenu(Iterator iterator)
|
||||
{
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
MenuItem menuItem = iterator.next();
|
||||
if (menuItem.isVegetarian())
|
||||
{
|
||||
write(menuItem.getName());
|
||||
writeln("\t\t", menuItem.getPrice());
|
||||
writeln("\t", menuItem.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private bool isVegetarian(string name, Iterator iterator)
|
||||
// {
|
||||
// while (iterator.hasNext())
|
||||
// {
|
||||
// MenuItem menuItem = iterator.next();
|
||||
// if (menuItem.getName() == name)
|
||||
// {
|
||||
// if (menuItem.isVegetarian())
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
}
|
Reference in New Issue