There are great tools at our disposal to ensure that system are designed to change rapidly while reducing negative impact these alterations can bring.
One such tool
DESIGN PATTERNS
Structural
Abstract Server Adapter
Behavioral
Template Method Interpreter
Object
Adapter Bridge Composite Decorator External Polymorphism Faade Proxy Null Object
Active Object Acyclic Visitor Command Iterator Observer State Strategy Visitor
Purpose
Creational: concerned with object creation Structural: concerned with composition of classes or objects Behavioral: concerned with ways classes or objects interact
Scope
Class: relationships between classes and derived classes; static Object: relationships between objects; dynamic
Purpose
Creational: concerned with object creation Structural: concerned with composition of classes or objects Behavioral: concerned with ways classes or objects interact
Scope
Class: relationships between classes and derived classes; static Object: relationships between objects; dynamic
Creational Patterns
Creational Patterns describe object-creation mechanisms that enable greater levels of reuse in evolving systems
Logical Model
Physical Model
Logical Model
It uses three types of primary actors
Physical Model
Uses two abstract classes Factory Product
Client uses an instance of a concrete subclass of Factory(ConcreteFactory) to create an instance of a concrete Product subclass (ConcreteProduct)
The ConcreteComputer and ConcreteComputerFactory classes found below extend these abstract class
class ConcreteComputer:Computer { int _mhz = 500; public override int Mhz { get { return _mhz; } }//Mhz }//ConcreteComputer class ConcreteComputerFactory:ComputerFactory { public override Computer GetComputer() { return new ConcreteComputer(); }//GetComputer }//ConcreteComputerFactory
Question
Clients generally obtain information from objects of interest (the subject) by calling the subjects methods But how can the client keep current if the subject keeps changing?
How do they know when to query the subject?
Weather-O-Rama
A weather station periodically measures temperature, humidity, and barometric pressure A driver object is provided that monitors the station and calls a certain method at regular intervals with new data:
void measurementsChanged( );
Humidity Sensor
Display 1
updates
Temperature Sensor
Weather Station
polls
updates
Display 2
updates
Pressure Sensor
Display 3
Nave Solution
Add code to measurementsChanged that notifies the observers
There are three initially:
Current conditions Statistics Forecast
public void measurementsChanged() { float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionsObserver.update(temp, humidity, pressure); statisticsObserver.update(temp, humidity, pressure); forecastObserver.update(temp, humidity, pressure); }
New observers can be added at will Subject doesnt change when new types of observers are created
-subject
Implementation Notes
The Subject maintains a list of Observers
Added when observers register
Notifying Observers
The notify method calls update for each observer How should observers respond? What about passing data to the observers?
New observers can be added at will Subject doesnt change when new types of observers are created
Pizza in Objectville
public Pizza orderPizza() { Pizza pizza = new Pizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } // 1 type only!
return pizza;
}
Here We Go Again!
As new pizza types arrive, we must change this code
If this is the only place it occurs, its not the end of the world Nonetheless, lets try to
Separate those things that vary from those that dont (again) And now that we know about Open-Closed:
Lets try to make this code extensible while being closed to modification
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
Refactoring orderPizza( )
public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type) { Pizza pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }
A Pizza-Creating Class
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); } else if (type.equals("pepperoni")) { pizza = new PepperoniPizza(); } else if (type.equals("clam")) { pizza = new ClamPizza(); } else if (type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; }