Presentation is loading. Please wait.

Presentation is loading. Please wait.

Behavioral Pattern: Strategy C h a p t e r 5 – P a g e 205 The Open-Closed Principle advocates designing software in such a way that it will absorb new.

Similar presentations


Presentation on theme: "Behavioral Pattern: Strategy C h a p t e r 5 – P a g e 205 The Open-Closed Principle advocates designing software in such a way that it will absorb new."— Presentation transcript:

1

2 Behavioral Pattern: Strategy C h a p t e r 5 – P a g e 205 The Open-Closed Principle advocates designing software in such a way that it will absorb new variations without having to introduce new fundamental structure, enabling the capabilities of a system to be extended without substantially changing the basic system. The Strategy Pattern attempts to accomplish this by encapsulating each algorithm in a family of algorithms and making them all interchangeable, thus allowing each algorithm to vary independently of the clients that use it. This permits a program to switch easily between algorithms without resorting to monolithic if-else statements. This approach allows the behavior in question to be modified at run-time and not just at design time.

3 The Strategy Pattern C h a p t e r 5 – P a g e 206 The Strategy declares an interface common to all supported algorithms, using this interface to call the algorithm defined by a ConcreteStrategy. The ConcreteStrategy implements the algorithm using the Strategy interface. The Context is configured with a ConcreteStrategy object, maintains a reference to a Strategy object, and may define an interface that lets the Strategy object access its data.

4 C h a p t e r 5 – P a g e 207 Non-Software Example: Airport Transportation Modes of transportation to an airport is an example of a Strategy. Several options exist, such as driving one's own car, taking a taxi, an airport shuttle, or a limousine service. For some airports, subways and helicopters are also available as a mode of transportation to the airport. Any of these modes of transportation will get a traveler to the airport, and they can be used interchangeably. The traveler must chose the Strategy based on tradeoffs between cost, convenience, and time.

5 C h a p t e r 5 – P a g e 208 Software Example: Event Handler The NetworkManagement context needs strategies for handling various events on the network. The Connection strategy is to respond by indicating a need for greater bandwidth. The Path strategy is to respond by indicating a need for some alternative path through the network. The LSP strategy is to respond by indicating a need for an alternative path through the network that meets specific label switched path requirements. (Note that this model utilizes both the Strategy Pattern and the Chain of Responsibility Pattern.)

6 C h a p t e r 5 – P a g e 209 Event Handler Strategy C++ Code #include using namespace std; typedef int Event; const Event LINK_1_BROKEN = 1; const Event LINK_2_BROKEN = 2; const Event CONGESTION = 3; const Event No_Event_Support = -1; class EventHandler { public: explicit EventHandler(EventHandler* hdlr = 0, Event evt = No_Event_Support); virtual const bool HasEventSupport(Event evt); virtual void SetHandler(EventHandler* hdlr, Event evt); virtual void HandleEvent(Event evt); virtual ~EventHandler() { cout << "Now in the EventHandler destructor" << endl; }; private: EventHandler* successor; Event currentEvent; };

7 C h a p t e r 5 – P a g e 210 //Set up a chain of event handlers EventHandler::EventHandler( EventHandler* hdlr, Event evt ) : successor(hdlr), currentEvent(evt) { } const bool EventHandler::HasEventSupport(Event incomingEvent) { return currentEvent == incomingEvent; } void EventHandler::SetHandler(EventHandler* hdlr, Event evt) { successor = hdlr; currentEvent = evt; } void EventHandler::HandleEvent (Event incomingEvent) { if (incomingEvent != currentEvent) { if (successor != 0) { cout << "HandleEvent () calling into successor" << endl; successor->HandleEvent(incomingEvent); } else { cout << "Base class help now follows" << endl; }

8 C h a p t e r 5 – P a g e 211 class Connection : public EventHandler { public: Connection(Event evt) : EventHandler(0, evt) { } virtual void HandleEvent(Event incomingEvent); }; void Connection::HandleEvent(Event incomingEvent) { if (HasEventSupport(incomingEvent)) { // Offer event support cout << "Here's some Connection Event support" << endl; cout << "You may need additional bandwidth" << endl << endl; } else { cout << "No support from Connection - Sorry!" << endl; cout << "Calling the base class event handler" << endl; EventHandler::HandleEvent(incomingEvent); }

9 C h a p t e r 5 – P a g e 212 class Path : public Connection { public: Path::Path(Connection* conx, Event evt) : Connection(0) { cout << "In the Path constructor" << endl; SetHandler(conx, evt); } void HandleEvent(Event incomingEvent) { if (HasEventSupport(incomingEvent)) { // Offer event support cout << "Here's some Path Event support" << endl; cout << "We need a new path" << endl << endl; } else { cout << "No support from Path - Sorry!" << endl; cout << "Calling the base class event handler" << endl; EventHandler::HandleEvent(incomingEvent); } };

10 C h a p t e r 5 – P a g e 213 class Lsp : public Connection { public: Lsp::Lsp(string lspID, Connection* conx, Event evt) : Connection(0) { cout << "Constructing Lsp: " << lspID << endl; lspName = lspID; SetHandler(conx, evt); } void HandleEvent(Event incomingEvent) { if (HasEventSupport(incomingEvent)) { // Offer event support cout << "At last, here's some LSP Event support:" << endl; cout << "We need an alternative path for " << lspName << endl << endl; } else EventHandler::HandleEvent(incomingEvent); } private: string lspName; };

11 C h a p t e r 5 – P a g e 214 void main() { // Set up a Path->LSP->Connection Chain of Responsibility Connection* connection = new Connection(CONGESTION); Lsp* lsp = new Lsp("LSP123", connection, LINK_1_BROKEN); Path* path = new Path(lsp, LINK_2_BROKEN); cout << endl << "Time to handle network events" << endl << endl; //A network event has occurred, e.g., CONGESTION //Let's see who can handle this event cout << "Let's simulate a network error: CONGESTION" << endl; path->HandleEvent(CONGESTION); //Another network event has occurred, e.g., LINK_1_BROKEN //Let's see who can handle this event cout << "Let's simulate another network error: LINK_1_BROKEN" << endl; path->HandleEvent(LINK_1_BROKEN); cout << "Let's simulate one more network error: LINK_2_BROKEN" << endl; path->HandleEvent(LINK_2_BROKEN); delete path; delete lsp; delete connection; }

12 C h a p t e r 5 – P a g e 215

13 Strategy Pattern Advantages C h a p t e r 5 – P a g e 216 With the Strategy Pattern, a family of algorithms can be defined as a class hierarchy and can be used interchangeably to alter an application’s behavior without changing its architecture. By encapsulating the algorithm separately, new algorithms complying with the same interface can easily be introduced. The application can switch strategies at run-time, and clients can choose the required algorithm without using a “switch” statement or a series of “if-else” statements. Data structures used for implementing the algorithm are completely encapsulated in Strategy classes, so the implementation of an algorithm can be changed without affecting the Context class.


Download ppt "Behavioral Pattern: Strategy C h a p t e r 5 – P a g e 205 The Open-Closed Principle advocates designing software in such a way that it will absorb new."

Similar presentations


Ads by Google