Design Patterns

CSCE 247 - Lecture 18 - 03/27/2019 OO Design Exercise: Building a Better Duck

Duck

quack() swim() fly() display()

// Other Methods

MallardDuck RedheadDuck

display() { .. } display() { .. } …

2 Adding new ducks

Duck

quack() swim() fly() display()

// Other Methods

MallardDuck RedheadDuck RubberDuck

display() { .. } display() { .. } display() { .. }

3 Why not override?

Duck WoodenDuck

quack() display() { .. } swim() @Override quack() { .. } fly() @Override fly() {.. } display()

// Other Methods

MallardDuck RedheadDuck RubberDuck

display() { .. } display() { .. } display() { .. } @Override fly() {.. }

4 Why not interfaces?

<> <> Duck Quackable Flyable swim() quack() display() fly()

// Other Methods

MallardDuck RedheadDuck RubberDuck WoodenDuck

display() { .. } display() { .. } display() { .. } display() { .. } fly() { .. } fly() { .. } quack() {... } quack() { .. } quack { .. }

5 How do we fix this mess?

Apply good OO design principles!

Step 1: Identify the aspects that vary and encapsulate them.

Duck Flying class behaviors 6 Step 2: Implement behaviors as classes

<> Principle - ProgramFlyBehavior to an interface,(GOOD) not an implementation.fly() Programming to an interface: Duck (BETTER… BUT NOT GREAT) Duck FlyWithWings FlyNotAllowed Duck d = new (BAD) swim() Inherit and override. swim() fly() fly() { .. } fly() { .. } MallardDuck() display() DuckProgramming d = new MallardDuck(); to an implementation: quack() d.performFly(); display() d.fly();MallardDuck d = new MallardDuck(); Flying/Quacking Duck Stilld.flyWithWings(); requires reimplementing the same MallardDuck behavior called in the behaviorsRequires multiple knowing times. what type of duck FlyBehavior flyB same way for all ducks. QuackBehaviorflyWithWings()MallardDuck quackB you’re using, and what methods it quackLoudly() performFly() { Only implement specific swim() has. performQuack()fly(); flyB.fly(); performFly()quack();display() version of behavior swim() } once. display() 7 HAS-A can be better than IS-A

Principle: Favor composition over inheritance.

<> Duck FlyBehavior

FlyBehavior flyB fly() QuackBehavior quackB

performQuack() FlyWithWings FlyNotAllowed performFly() swim() fly() { .. } fly() { .. } display() setFlyBehavior() setQuackBehavior() <> QuackBehavior

quack() MallardDuck RedheadDuck RubberDuck NormalQuack Squeek display() { .. } display() { .. } display() { .. } quack() { .. } quack() { .. } 8 Challenge - Duck Call

A duck call is a device that hunters use to mimic the sound of a duck. How would you implement a duck call in this framework?

9 Enter...

Don’t just describe classes, describe problems.

Patterns prescribe design guidelines for common problem types.

10 Guidelines, not solutions

“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem in such a way that you can use this solution a million times over, without ever doing it the same way twice.” -

11 Categories of design patterns

1. Behavioral Describe how objects interact. 2. Creational Decouple a client from objects it instantiates. 3. Structural Clean organization into subsystems.

12 Why use design patterns?

1. Good examples of OO principles. 2. Faster design phase. 3. Evidence that system will support change. 4. Offers shared vocabulary between designers. 13 You already applied one pattern

Strategy Pattern

Defines a family of algorithms, encapsulates them, makes them interchangeable.

14 - Motivation

15 Observer Pattern - Definition

(When data changes, Change Request subscribers are notifed)

Updated Data (These objects have Object subscribed to the Subject to receive Subject Updated Data update(){updates when data Object changes)// do something UpdatedSubscribe Data Object }

Object update(){

// do something

}

Subscriber Objects update(){ // do something }

16 Observer Pattern Example Pet Feeding

update(){ fillBowl(“puppy chow”); if (bowl.getFood() == “puppy chow”) eat(); } addObserver(); update(); Dog

Food Bowl Cat

removeObserver(Mouse); update(){ Mouse fillBowl(String food){ if (bowl.getFood() != notify(); “ahi tuna”) // .... angryMeow(); } update(){ } notify(){ if (bowl.GetObservers() for o in observers{ contains Cat) o.update(); removeObserver(this); } else } eat(); 17 } Observer Pattern - In Practice

<> notify() { <> Observable for observer in observers{ Observer

observer.update() addObserver(Observer) } update() removeObserver(Observer) } notify()

ConcreteObserver 1 observers * ConcreteObservable ConcreteObservable subject State state List observers 1 subject 1 update() setSubject(ConcreteObservable) addObserver(ConcreteObserver) // Action methods removeObserver(ConcreteObserver) notify() getState() update(){ setState() state= subject.getState() } 18 Benefits of Observer Pattern

When objects are loosely coupled, they can interact while lacking knowledge of each other.

1. Can add new observers at any time. 2. Never need to modify subject. 3. Easy code reuse. 4. Easy change. 19 - Motivation

20 Visitor Pattern - Definition

(Theaccept(Visitor) items tell the Collection visitor what they visit(Collection) are, and the visitor Visitor acts accordingly) accept(Visitor) accept(Visitor)

visit(Item) Client (Visitors can ItemSet Item traverse the data structure and gather accept(Visitor) accept(Visitor) (The client wants to information.) perform actions using data from some structure) Item Item

(Items are instructed to tell the visitor who they are.) 21 Visitor Pattern Example Grocery Checkout

accept(visitor){ for(item in Items()) item.accept(visitor); Cart } accept(TagScanner); accept(visitor); visit(Cart); Cashier Dairy Ramen Products Tag Scanner accept(visitor); accept(visitor);

visit(Cheese); Cheese Milk visit(Cheese c){ price+= c.getPrice(); accept(visitor){ } visitor.visit(this); } 22 Visitor Pattern - In Practice

<> Client Element

accept(ConcreteVisitor)

<> ConcreteElementA ConcreteElementB Visitor List members accept(ConcreteVisi visit(ConcreteElementA) tor) visit(ConcreteElementB) accept(ConcreteVisitor) getMembers()

ConcreteVisitor accept(ConcreteVisitor visitor){ accept(ConcreteVisitor for element in this.getMembers(){ visitor){ visit(ConcreteElementA) element.accept(visitor) visitor.visit(this) visit(ConcreteElementB) } }

23 Benefits of Visitor Pattern

1. Can add operations to a collection without changing the collection structure. 2. Thus, adding new functionality and operations is easy. 3. Operation code is centralized.

24 Activity

Building a weather monitoring application. Generates three displays: current conditions, weather statistics, simple forecast. Design system using either visitor or observer pattern.

Provided: To Implement:

Pulls data from.

Humidity Sensor Displays to Weather Display Temperature Physical Data System Hardware Sensor Hardware Pressure Sensor

25 Activity Solution - Observer Pattern

<> <> <> Display Observable Observer

display() addObserver(observer) update() removeObserver(observer) notify()

WeatherData

List Displays CurrentConditions ForecastDisplay StatisticsDisplay Display addObserver(Observer) WeatherData data WeatherData data removeObserver(Observer) WeatherData data notify() update() update() update() display() display() getTemperature() display() getHumidity() getPressure() measurementsChanged()

26 Factory Pattern - Motivation

27 Factory Pattern - Motivation

Pizza orderPizza(){ Pizza pizza = new Pizza();

pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } 28 Factory Pattern - Motivation

Pizza orderPizza(String type){ Pizza pizza; if (type.equals(“cheese”)){ pizza = new CheesePizza(); else if(type.equals(“pepperoni”)){ pizza = new PepperoniPizza(); } // Prep methods } 29 Factory Pattern - Motivation

Pizza orderPizza(String type){ Pizza pizza; if (type.equals(“cheese”)){ pizza = new CheesePizza(); else if(type.equals(“pepperoni”)){ pizza = new PepperoniPizza(); } else if(type.equals(“veggie”)){ pizza = new VeggiePizza(); } // Prep methods } 30 Factory Pattern - Motivation

Pizza orderPizza(String type){ Pizza pizza;

pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; SimplePizzaFactory }

31 The Simple Factory

PizzaStore SimplePizzaFactory <> Pizza SimplePizzaFactory factory createPizza(String) prepare() orderPizza(String) bake() cut() box()

Pizza createPizza(String s){ if(s.equals(“Pepperoni”)) VeggiePizza return new

PepperoniPizza(); CheesePizza PepperoniPizza prepare() // Other pizza types bake() } prepare() prepare() cut() bake() bake() box() cut() cut() box() box()

32 Franchising the Factory

PizzaStore <> <> PizzaFactory Pizza PizzaFactory factory createPizza(String) prepare() orderPizza(String) bake() cut() box()

NewYorkPizzaFactory ChicagoPizzaFactory createPizza(String) createPizza(String) NYVeggiePizza NYPepperoniPizza prepare() ChicagoPepperoniPizza ChicagoVeggiePizza prepare() bake() cut() prepare() bake() prepare() cut() bake() box() bake() cut() box() cut() box() box()

33 Factory Pattern - Definition

Defines an interface for creating an object, but lets subclasses decide which object to instantiate. Allows reasoning about creators and products.

<> <> Pizza PizzaFactory prepare() createPizza(String) bake() NYVeggiePizza cut() box() prepare() ChicagoVeggiePizzabake() cut() prepare()box() NewYorkPizzaFactory ChicagoPizzaFactory bake() cut() createPizza(String) createPizza(String) box()

34 Factory Pattern - In Practice

Client <> <> ProductB ProductA // methods // methods

Concrete ProductA1

ConcreteFactory1 Concrete ProductA2 <> createProductA() Factory createProductB() Concrete ProductB1 createProductA() ConcreteFactory2 Concrete createProductB() ProductB2 createProductA() createProductB()

35 Benefits of Factory Pattern

1. Loose coupling. 2. Creation code is centralized. 3. Easy to add new classes. 4. Lowered class dependency (can depend on abstractions, not concrete classes). 36 Why not use a design pattern?

What are the drawbacks to using patterns?

● Potentially over-engineered solution. ● Increased system complexity. ● Design inefficiency.

How can we avoid these pitfalls?

37 Resources

Web: ● oodesign.com ● c2.com/cgi/wiki?PatternIndex

Book: ● Head First Design Patterns, by Eric Freeman, Bert Bates, Kathy Sierra, and Elisabeth Robson. ● Design Patterns: Elements of Reusable Object Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (Gang of Four)

38 We Have Learned

When in doubt: 1. Reason about the problem, then the objects. 2. Patterns provide templates for OO design.

Patterns come in many flavors. Think about patterns and GRADS (hint, hint).

39 Next Time

● Design Patterns, round 2 ● Homework ○ Due April 7 ○ Questions on class diagrams? Design?

40