CS 210 Final Review November 28, 2006. CS 210 Adapter Pattern.
CS 210 Review Session October 5 th, 2006. Head First Design Patterns Chapter 4 Factory Pattern.
-
Upload
regina-arnold -
Category
Documents
-
view
214 -
download
0
Transcript of CS 210 Review Session October 5 th, 2006. Head First Design Patterns Chapter 4 Factory Pattern.
CS 210
Review Session
October 5th, 2006
Head First Design Patterns
Chapter 4
Factory Pattern
Pizza creationPizza orderPizza(String type){
if (type.equals(“cheese”)) {pizza = new CheesePizza();
} else if type.equals(“greek”)) {pizza = new GreekPizza();} else if type.equals(“pepperoni”)) {pizza = new PepperoniPizza();} pizza.prepare();pizza.bake();pizza.cut();pizza.box()
}
Identifying the aspects that vary
If the pizza shop decides to change the types of pizza it offers, the orderPizza method has to be changed.
Pizza examplePizza orderPizza(String type){
if (type.equals(“cheese”)) {pizza = new CheesePizza();
} else if type.equals(“greek”)) {pizza = new GreekPizza();} else if type.equals(“pepperoni”)) {pizza = new PepperoniPizza();} pizza.prepare();pizza.bake();pizza.cut();pizza.box()
}
Part that varies.
Part that remains constant
Encapsulating object creation
if (type.equals(“cheese”)) {pizza = new CheesePizza();
} else if type.equals(“greek”)) {pizza = new GreekPizza();} else if type.equals(“pepperoni”)) {pizza = new PepperoniPizza();}
SimplePizzaFactory
Building a simple pizza factorypublic 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;
}
}
Reworking the PizzaStore Classpublic class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
Complete example for Simple Factory
SimplePizzaFactory factory = new SimplePizzaFactory(); PizzaStore store = new PizzaStore(factory);
Pizza pizza = store.orderPizza("cheese");
Simple Factory Defined
PizzaStoreorderPizza()
SimplePizzaFactorycreatePizza()
Pizzaprepare()bake()cut()box() CheesePizza
VeggiePizza
ClamPizza
ClamPizza
Creating multiple factories
PizzaStore
NYPizzaFactory
ChicagoPizzaFactory
Creating multiple instances
NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
Pizza pizza = nyStore.orderPizza("cheese");
ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore chicagoStore = new PizzaStore(chicagoFactory);
Pizza pizza = chicagoStore.orderPizza("cheese");
Alternate approach – Abstract method – a framework for the pizza store
public abstract class PizzaStore { abstract Pizza createPizza(String item);
public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }}
Allowing the subclasses to decide
PizzaStorecreatePizza()orderPizza()
NYStylePizzaStorecreatePizza()
ChicagoStylePizzaStorecreatePizza()
A factory method handles object creation and encapsulates it in the subclass. This decouples the client code in the super class from the object creation that happens in the subclass.
Factory Method Pattern
PizzaStorecreatePizza()orderPizza()
NYStylePizzaStorecreatePizza()
ChicagoStylePizzaStorecreatePizza()
Pizza
NYStyleCheesePizzaNYStyleCheesePizza
NYStyleCheesePizzaNYStyleCheesePizza
ChStyleCheesePizzaChStyleCheesePizza
ChStyleCheesePizzaChStyleCheesePizza
Creator Classes
Product Classes
Factory Method Pattern defined
The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclass.
Factory Method Pattern Defined
Product
ConcreteProduct ConcreteCreator
factoryMethod()
CreatorfactoryMethod()anOperation()
Looking at object dependencies
PizzaStore
NyStyleCheezePizza
NyStyleCheezePizza
NyStyleCheezePizza
NyStyleClamPizza
ChicagoCheezePizza
ChicagoCheezePizza
ChicagoCheezePizza
ChicagoClamPizza
Design Principle
Dependency Inversion PrincipleDepend upon abstractions. Do not depend upon concrete classes.
“High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.”
[The Dependency Inversion Principle has been proposed by Robert C. Martin]
Applying the principle
PizzaStore
NyStyleCheezePizza
NyStyleCheezePizza
NyStyleCheezePizza
NyStyleClamPizza
ChicagoCheezePizza
ChicagoCheezePizza
ChicagoCheezePizza
ChicagoClamPizza
Pizza
Pizza is an abstract class
Some guidelines to help with the principle
Try and avoid having variables that refer to a concrete class
Try and avoid deriving from a concrete class
Try and avoid overriding an implemented method
Extending the factory pattern…
Expanding the Pizza store example How do we deal with families of ingredients?
• Chicago: FrozenClams, PlumTomatoSauce, ThickCrustDough, MozzarellaCheese
• New York: FreshClams, MarinaroSauce, ThinCrustDough, ReggianoCheese
• California: Calamari, BruuuschettaSauce, VeryThinCrust, GoatCheese
Building the ingredient factories
public interface PizzaIngredientFactory { public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clams createClam();
}
Building NY ingredient factorypublic class NYPizzaIngredientFactory implements PizzaIngredientFactory { public Dough createDough() {
return new ThinCrustDough();}
public Sauce createSauce() {return new MarinaraSauce();
} public Cheese createCheese() {
return new ReggianoCheese();}
public Veggies[] createVeggies() {Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };return veggies;
} public Pepperoni createPepperoni() {
return new SlicedPepperoni();}public Clams createClam() {
return new FreshClams();}
}
Reworking the pizzaspublic abstract class Pizza {
String name;Dough dough;Sauce sauce;Veggies veggies[];Cheese cheese;Pepperoni pepperoni;Clams clam;abstract void prepare();void bake() {
System.out.println("Bake for 25 minutes at 350");}void cut() {
System.out.println("Cutting the pizza into diagonal slices");}void box() {
System.out.println("Place pizza in official PizzaStore box");}void setName(String name) {
this.name = name;}String getName() {
return name;}public String toString() { \\ code to print pizza here}
}
Abstract Factory Pattern defined
The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
ProductA1
Abstract Factory Pattern
<<Interface>>AbstractFactory
CreateProductA()CreateProductB()
ConcreteFactory1
CreateProductA()CreateProductB()
ConcreteFactory2
CreateProductA()CreateProductB()
Client
<<Interface>>AbstractProdcutA
ProductA1
<<Interface>>AbstractProdcutB
ConcreteFactory1
CreateProductA()CreateProductB()
ProductB1
ProductA2
ProductB2
ProductA1
Abstract Factory Pattern example
<<Interface>>PizzaIngFactory
CreateDough()CreateCheese()
ConcreteFactory1
CreateProductA()CreateProductB()
ChicPizzaIngFctry
CreateDough()CreateCheese()
Pizza
<<Interface>>Dough
ThinCrust
<<Interface>>Cheese
NYPizzaIngFctry
CreateDougn()CreateCheese()
Reggiano
ThickCrust
Mozzarella
Summary so far.. OO Basics
• Abstraction• Encapsulation• Inheritance• Polymorphism
OO Principles• Encapsulate what varies• Favor composition over inheritance• Program to interfaces not to
implementations• Strive for loosely coupled designs
between objects that interact• Classes should be open for extension but
closed for modification.• Depend on abstracts. Do not depend on
concrete classes.
OO Patterns• Strategy Pattern defines a family of
algorithms, Encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
• Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
• Decorator Pattern – attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative for sub-classing for extending functionality
• Abstractor Factory – Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
• Factory Method – Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to the subclasses.
Head First Design Patterns
Chapter 6
Command Pattern
Encapsulating Invocation
Motivating problem description
Build a remote that will control variety of home devices
Sample devices: lights, stereo, TV, ceiling light, thermostat, sprinkler, hot tub, garden light, ceiling fan, garage door
Introducing the command pattern
CreateCommandObject
execute()
setCommand
execute()action1action2
creatCommandObject()
setCommand()
execute()
action_X()
Command Pattern for home automation
action()
execute(){ receiver.action()}
execute()
execute()
execute()
An encapsulated Request
Invoker
Command Pattern defined
The Command Pattern encapsulates a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.
Command Pattern Class Diagram
Client Invoker
setCommand()
<<Interface>>Command
execute()undo()
Receiver
action()
ConcreteCommand
execute()undo()
Command Pattern Class Diagram for Home automation
RemoteLoader
RemoteControl
onCommandsoffCommandssetCommand()onButtonPushed()offButtonPushed()
<<Interface>>Command
execute()undo()
Light
on()off()
LightOnCommand
execute()undo()
LightOffCommand
execute()undo()
Command pattern – Undo operation
Eclipse code review
Macro Commands – Party modepublic class MacroCommand implements Command {
Command[] commands; public MacroCommand(Command[] commands) { this.commands = commands;}
public void execute() {for (int i = 0; i < commands.length; i++) {
commands[i].execute();}
}
public void undo() {for (int i = 0; i < commands.length; i++) {
commands[i].undo();}
}}
Macro Command – Party mode
Eclipse code review
Page 228 – Head First Design Patterns
Summary so far.. OO Basics
• Abstraction• Encapsulation• Inheritance• Polymorphism
OO Principles• Encapsulate what varies• Favor composition over inheritance• Program to interfaces not to implementations• Strive for loosely coupled designs between objects that interact• Classes should be open for extension but closed for modification.• Depend on abstracts. Do not depend on concrete classes.
Summary so far… OO Patterns
• Strategy Pattern defines a family of algorithms, Encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
• Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
• Decorator Pattern – attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative for sub-classing for extending functionality
• Abstractor Factory – Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
• Factory Method – Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to the subclasses.
• Command Pattern – Encapsulates a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.