iterator
This commit is contained in:
parent
afb0c148a1
commit
935f9c7563
|
@ -10,6 +10,7 @@
|
||||||
2. [Наблюдатель](observer/)
|
2. [Наблюдатель](observer/)
|
||||||
3. [Команда](command/)
|
3. [Команда](command/)
|
||||||
4. [Шаблонный метод](templatemethod/)
|
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