cmpsci&220&programming&methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf ·...
TRANSCRIPT
![Page 1: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/1.jpg)
CMPSCI 220 Programming Methodology
07: Decorator, Singleton, & Factory Pattern
![Page 2: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/2.jpg)
ObjectivesDecorator PatternLearn how objects can gain new responsibilities at runtime.Apply the decorator pattern in Scala.
Singleton PatternLearn how objects can be represented as singleton objects. We knowhow to do this in Scala. What does it look like in Java?
Factory PatternWe have been introduced to the factory pattern already, but we didn’t make it obvious. We will see how Scala handles this and what it looks like in Java.
![Page 3: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/3.jpg)
i-clicker Question!
What design principle is applied to objects with the observer pattern?
A. Objects are tightly coupled to improve flexibilityB. Objects are loosely coupled to improve flexibilityC. Objects are combined to improve flexibilityD. Objects are eliminated to reduce complexityE. I am not sure
![Page 4: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/4.jpg)
Welcome to Starbuzz Coffee!
This is Peter Gibbons (aka Jimmy). He is a sad man because he is upset with the developer of Starbuzz's ordering system. Every time there is a new beverage it takes forever for the beverage to become available in their system. Not to mention the system is sooo slow!
This is Milton Waddams. He didn't take CMPSCI 220 at UMass Amherst. He thinks he is awesome, but he is not. He is the mastermind behind the poorly designed ordering system at Starbuzz. He can't code himself out of a paper bag. He really likes staplers.
![Page 5: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/5.jpg)
Starbuzz Ordering System Design
description
getDescription()cost()
// Other useful methods
Beverage
cost()
HouseBlend
cost()
DarkRoast
cost()
Decaf
cost()
Espresso
"Oh Yeah! This is a good design!"Milton, you SUCK!
In addition to your coffee, you can also ask for several condiments like steamed milk, soy, and mocha, and have it all topped off with whipped milk. Starbuzz charges a bit for each of these, so they really need to get them build into their ordering system.
How might this be done in this design?
![Page 6: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/6.jpg)
Class Explosion!!!
"So, what is your point..."
![Page 7: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/7.jpg)
Class Explosion!!!
"You are FIRED! And leave the stapler!"
How can we fix this?
![Page 8: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/8.jpg)
Starbuzz Ordering System Design Take 2
descriptionmilk, soy, mocha, whip
getDescription()cost()hasMilk()setMilk()hasSoy()hasMocha()setMocha()hasWhip()setWhip()// And other useful methods...
Beverage
cost()
HouseBlend
cost()
DarkRoast
cost()
Decaf
cost()
Espresso
The superclass cost() will calculate the costs for all of the condiments, while the overridden cost() in the subclasses will extend that functionality to include costs for the specific beverage type.
Each cost() method needs to compute the cost of the beverage and then add in the condiments by calling the superclass implementation of cost().
![Page 9: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/9.jpg)
Your Turn!
class Beverage def cost: Double =
class DarkRoast extends Beverage val description = "Most Excellent Dark Roast"def cost: Double =
Write the cost() methods for the two classes below (pseudo-Scala is okay)
![Page 10: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/10.jpg)
What Might Impact This Design?
Price changes for condiments will force us to alter existing code.
New condiments will force us to add new methods and alter the cost method of the superclass.
We may have new beverages. For some of these beverages (iced tea?), the condiments may not be appropriate, yet the Tea subclass will still inherit methods like hasWhip().
What if a customer wants a double mocha or espresso?
![Page 11: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/11.jpg)
The Open-Closed Principle
Design Principle: Classes should be open for extension, but closed for modification.
How does this relate to our existing ordering system design?
Our goal is to allow classes to be easily extended to incorporate new behavior without modifying existing code. What do we get if we accomplish this?Designs that are resilient to change and flexible enough to take on new functionality to meet changing requirements.
![Page 12: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/12.jpg)
Meet The Decorator Pattern
1. Take a DarkRoast object.
2. Decorate it with a Mocha object.
3. Decorate it with a Whip object.
4. Call the cost() method and rely on delegation to add on the condiment costs.
![Page 13: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/13.jpg)
The Decorator Pattern Defined
The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
![Page 14: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/14.jpg)
Decorator Class Diagram
methodA()methodB()// Other useful methods
<Component>
methodA()methodB()// Other useful methods
ConcreteComponent
methodA()methodB()// Other useful methods
Decorator
val wrappedObj: Component
methodA()methodB()newBehavior()// Other useful methods
ConcreteDecoratorA
val wrappedObj: Componentval newState
methodA()methodB()newBehavior()// Other useful methods
ConcreteDecoratorB
Each decorator HAS-A component, which means that the decorator has an instance variable that holds a reference to a component.
Decorators implement the same trait or abstract class as the component they are going to decorate.
![Page 15: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/15.jpg)
Starbuzz's New Design
getDescription()cost()// Other useful methods
<Beverage>
cost()
HouseBlend
cost()
DarkRoast
cost()
Espresso
cost()
Decaf
getDescription()
CondimentDecorator
beveragecost()getDescription()
Milk
beveragecost()getDescription()
Mocha
beveragecost()getDescription()
Soy
beveragecost()getDescription()
Whip
![Page 16: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/16.jpg)
Implementing the Starbuzz Application
src/main/scala/cs220/Decorator.scala
![Page 17: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/17.jpg)
Singleton Pattern
It is often the case that we desire only a single instance of a class. This single instance is referred to as a singleton object.
![Page 18: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/18.jpg)
Singleton Use Case: Databases
In many real-world applications a database is necessary for storing large amounts of data.
Typically, we are interacting with only a single database instance. That is, we do not want to create a “new instance” of a database each time we interact with it. Rather, we want to interact with the same database.
![Page 19: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/19.jpg)
Singleton in Java: Interface
package java.singleton;
public interface Database public String get(String key);public String set(String key, String value);
![Page 20: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/20.jpg)
Singleton in Java: Implementationpublic class MyDatabase implements Database private Map<String, String> db;;
private MyDatabase() db = new HashMap<>();;
@Overridepublic String get(String key) return db.get(key);;
@Overridepublic String set(String key, String value) db.put(key, value);;return value;;
…
![Page 21: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/21.jpg)
Singleton in Java: Implementationpublic class MyDatabase implements Database private Map<String, String> db;;
……
private static MyDatabase instance = null;
public static MyDatabase getInstance() if (instance == null)
instance = new MyDatabase();return instance;
![Page 22: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/22.jpg)
Implementing the Singleton Pattern
src/main/java/j/singleton/*.java
![Page 23: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/23.jpg)
Singleton in Scala: Trait
package scala.singleton
trait Database def get(key: String): Stringdef set(key: String, value: String): String
![Page 24: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/24.jpg)
Singleton in Scala: Implementation
object MyDatabase extends Database private var db = Map[String, String]()
override def get(key: String): String = db(key)
override def set(key: String, value: String): String = db = db + (key -> value)value
![Page 25: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/25.jpg)
Implementing the Singleton Pattern
src/main/scala/s/singleton/*.scala
![Page 26: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/26.jpg)
Factory Pattern
The factory pattern is a creational patternwhich uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created.
This is done by creating objects by calling a factory method that creates the object and returns it as an abstract class or interface type.
This allows for easily trading in different implementations without affecting client code that calls the factory method.
![Page 27: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/27.jpg)
Factory Pattern Use Case
Imagine we want to create an application that draws shapes to the screen.
In addition, we want to be able to add new shape implementations to our application without affecting the code that uses the shapes.
![Page 28: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/28.jpg)
Factory Example
val s1 = new Circles1.draw
![Page 29: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/29.jpg)
Factory Example
val s1 = new Circles1.drawval s2 = new Squares2.draw
![Page 30: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/30.jpg)
Factory Example
val s1 = new Circles1.drawval s2 = new Squares2.draw
What if we wanted our circles to be drawn differently?
![Page 31: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/31.jpg)
Factory Example
val s1 = new Circleval s1 =
new BrushedCircles1.drawval s2 = new Squares2.draw
What if we wanted our circles to be drawn differently?
![Page 32: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/32.jpg)
Factory Example
val s1 = new Circleval s1 =
new BrushedCircles1.drawval s2 = new Squares2.draw
What if we wanted our circles to be drawn differently?
What is the problem here?
![Page 33: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/33.jpg)
Factory Example
val s1 = new Circleval s1 =
new BrushedCircles1.drawval s2 = new Squares2.draw
What if we wanted our circles to be drawn differently?
Is there a way to improve on this design so we need not change the “client” code?
![Page 34: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/34.jpg)
Factory UML Diagram
![Page 35: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/35.jpg)
Factory Example
val f = new Factoryval s1 = f.shape(“circle”)s1.draw
![Page 36: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/36.jpg)
Factory Example
val f = new Factoryval s1 = f.shape(“circle”)s1.drawval s2 = f.shape(“square”)s2.draw
![Page 37: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/37.jpg)
Factory Example
Now, imagine we change the implementation of our circle.
val f = new Factoryval s1 = f.shape(“circle”)s1.drawval s2 = f.shape(“square”)s2.draw
![Page 38: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/38.jpg)
Factory Example
Now, imagine we change the implementation of our circle.
This will not change the client code requesting shapes.
val f = new Factoryval s1 = f.shape(“circle”)s1.drawval s2 = f.shape(“square”)s2.draw
![Page 39: CMPSCI&220&Programming&Methodologyumass-cs-220.github.io/weeks/04/07-decorator.pdf · 2015-12-22 · Objectives Decorator&Pattern Learnhow$objects$cangainnew$responsibilities$at$runtime](https://reader033.vdocuments.us/reader033/viewer/2022042112/5e8e53b82ec4c25afe06261e/html5/thumbnails/39.jpg)
Implementing the Factory Pattern
src/main/scala/j/factory/*.javasrc/main/scala/s/factory/*.scala