Design Pattern Examples
Overview of object-oriented design patterns
Visitor_Element_Classes.cpp
Go to the documentation of this file.
1
5
6#include <iostream>
7#include <sstream>
8
9#include "helpers/formatstring.h"
10#include "helpers/stringlist.h"
11
14#include "Visitor_Village.h"
15
16namespace { // Anonymous
17
25 bool are_vector_contents_the_same(StringList& left, StringList& right)
26 {
27 bool match = left.size() == right.size();
28
29 if (match)
30 {
31 for (StringList::iterator leftIter = std::begin(left);
32 leftIter != std::end(left);
33 leftIter++)
34 {
35 if (std::find(std::begin(right), std::end(right), *leftIter) == std::end(right))
36 {
37 match = false;
38 break;
39 }
40 }
41 }
42
43 return match;
44 }
45}
46
48{
49 bool Visitor_Shop::DoesShopSellItem(std::string item)
50 {
51 return ingredientsForItems.contains(item);
52 }
53
54
55 bool Visitor_Shop::IsItemInStock(std::string item)
56 {
57 return Inventory.contains(item) && Inventory[item] > 0;
58 }
59
60
61 void Visitor_Shop::AddItemToInventory(std::string item)
62 {
63 if (!Inventory.contains(item))
64 {
65 Inventory.insert(std::pair(item, 1));
66 }
67 else
68 {
69 Inventory[item]++;
70 }
71 }
72
73
75 {
76 std::ostringstream output;
77
78 for (std::string& item : items)
79 {
80 if (output.tellp() != 0)
81 {
82 output << ", ";
83 }
84 output << item;
85 }
86 return output.str();
87 }
88
89
91 {
92 bool orderPlaced = false;
93 StringList outOfStockItems;
94 StringList itemsInThisShop;
95
96 for (std::string& item : items)
97 {
98 if (DoesShopSellItem(item))
99 {
100 if (!IsItemInStock(item))
101 {
102 outOfStockItems.push_back(item);
103 }
104 itemsInThisShop.push_back(item);
105 }
106 }
107
108 if (!itemsInThisShop.empty())
109 {
110 std::cout
111 << Helpers::formatstring(" %s: Received an order for %s.",
112 Name().c_str(), StringizeList(itemsInThisShop).c_str())
113 << std::endl;
114 orderPlaced = true;
115 }
116 if (!outOfStockItems.empty())
117 {
118 for (std::string& itemToOrder : outOfStockItems)
119 {
120 if (!ingredientsForItems[itemToOrder].empty())
121 {
122 std::cout
123 << Helpers::formatstring(" %s: %s out of stock, ordering ingredients to make more...",
124 Name().c_str(), itemToOrder.c_str())
125 << std::endl;
126 OrderVisitor visitor(ingredientsForItems[itemToOrder]);
127 village->Accept(&visitor);
128 if (are_vector_contents_the_same(visitor.ItemsReceived, ingredientsForItems[itemToOrder]))
129 {
130 // verify the ingredients received matches the ingredients needed.
131 // only then add 1 to the inventory.
132 AddItemToInventory(itemToOrder);
133 }
134 else
135 {
136 std::cout
137 << Helpers::formatstring(" %s: Error! Ordered %s but only received %s.",
138 Name().c_str(), StringizeList(ingredientsForItems[itemToOrder]).c_str(),
139 StringizeList(visitor.ItemsReceived).c_str())
140 << std::endl;
141 }
142 }
143 else
144 {
145 // The ordered item has no ingredients so the
146 // ordered item will be magically added to inventory
147 std::cout
148 << Helpers::formatstring(" %s: %s out of stock, making...",
149 Name().c_str(), itemToOrder.c_str())
150 << std::endl;
151 AddItemToInventory(itemToOrder);
152 }
153 }
154 }
155 return orderPlaced;
156 }
157
158
159 void Visitor_Shop::PickupOrder(StringList items, StringList& itemsToBePickedUp)
160 {
161 for (std::string& item : items)
162 {
163 // If this shop sells the item and the item is in stock then
164 if (DoesShopSellItem(item))
165 {
166 if (IsItemInStock(item))
167 {
168 itemsToBePickedUp.push_back(item);
169 }
170 else
171 {
172 std::cout
173 << Helpers::formatstring(" Error! %s: Item %s is not in the inventory when it should be.",
174 Name().c_str(), item.c_str())
175 << std::endl;
176 }
177 }
178 }
179
180 if (!itemsToBePickedUp.empty())
181 {
182 StringList itemsReceivedFromThisShop;
183 // Reduce inventory for the ordered items
184 for (std::string& itemToBePickedUp : itemsToBePickedUp)
185 {
186 if (DoesShopSellItem(itemToBePickedUp))
187 {
188 Inventory[itemToBePickedUp]--;
189 itemsReceivedFromThisShop.push_back(itemToBePickedUp);
190 }
191 }
192
193 std::string output = StringizeList(itemsReceivedFromThisShop);
194 std::cout
195 << Helpers::formatstring(" %s: Order picked up for %s.", Name().c_str(), output.c_str())
196 << std::endl;
197 }
198 }
199
200} // end namespace
Declaration of the Visitor base class and the various shop classes used in the Visitor Pattern.
Implementation of the OrderVisitor class used in the Visitor Pattern.
A visitor used for ordering items from various shops. The user starts with an instance of this class ...
StringList ItemsReceived
List of items received from an order/pickup process.
void PickupOrder(StringList items, StringList &itemsToBePickedUp)
Pick up the items sold by this shop (assumes the items were ordered already). Basically,...
bool DoesShopSellItem(std::string item)
Determine if this shop sells the specified item.
std::string StringizeList(StringList items)
Convert a string list to a comma-delimited string. Useful for displaying the list.
bool PlaceOrder(StringList items)
Place an order for the specified items. If the inventory is empty, replenish the inventory by visitin...
std::map< std::string, int > Inventory
Inventory for this shop.
void AddItemToInventory(std::string item)
Add the specified item to this shop's inventory.
bool IsItemInStock(std::string item)
Determine if this shop has the specified item in stock.
Declaration of the Visitor_Village class used in the Visitor Pattern.
std::vector< std::string > StringList
Typedef for a vector of std::string.
The namespace containing all Design Pattern Examples implemented in C++.
std::string formatstring(const char *fmt,...)
Use the given string and arguments to return a buffer containing the formatted string....