TDDB84 - IDA > HomeTDDB84/lectures/2015/final_lecture.pdf · Writing Papers, tips • Use •...
Transcript of TDDB84 - IDA > HomeTDDB84/lectures/2015/final_lecture.pdf · Writing Papers, tips • Use •...
TDDB84Summary & wrap-up & some tips & some design
patterns & some other stuff
tisdag 20 oktober 15
Agenda
• Course goals, expectations
• Writing papers: FAQ
• Design Patterns revisited
• Course summary
• Life after the course
tisdag 20 oktober 15
Course goals
Identify and explain software design principles and design patterns in existing object-oriented software.
Lab 1, 2
tisdag 20 oktober 15
Course goals
Apply software design principles and design patterns when working with existing object-oriented software.
Lab 1, 3
tisdag 20 oktober 15
Course goals
Describe the purpose and consequences of design patterns in object-oriented software.
Lab 2, 3, final paper
tisdag 20 oktober 15
Course goals
Critically evaluate software design principles and design patterns in relationship to software qualities.
Lab 3, final paper
tisdag 20 oktober 15
Course goals
Analyze the relationship between software design principles, design patterns, programming languages and
application frameworks.
Final paper
tisdag 20 oktober 15
Expectations
• Learn about design patterns
• Learn when to use design patterns
• Learn about design patterns in real software
• Learn about the consequences of design patterns
tisdag 20 oktober 15
Writing Papers, FAQ
tisdag 20 oktober 15
Writing Papers, tips
• Be
• specific
• precise
• formal
• direct
• unapologetic
tisdag 20 oktober 15
What is complexity? Design complexity, cyclomatic complexity?
This is not a popular science text. Refrain from wording that is ambiguous or less well defined (”forgiving”, ”good”, ”bad”, ”easy”)
Do not say something is ”very hard”, use a reference and be precise about what exactly that reference says
Do not say you ”will” do something, or ”intends”, be direct and state what you DO, or have DONE.
You do not have to state ”someone made me write this”, or ”Due to time constraints”: you will ALWAYS have external constraints on your work, as does everyone else. Write about what you have done, do not make excuses for what you have not done.
Writing Papers, tips
• Use
• references
• the style of research papers as a guide
• the hourglass style
• your team
tisdag 20 oktober 15
Back up all claims with references
Check your wording & justifications against academic publications, not previous years’ reports.
Everything before the narrow part should lead to the waist, and everything after should relate to the waist.
Don’t let your paper be overly focused on background material: you need to introduce only that which is necessary for someone else of approximately your own backgrounds (before the course) to understand the core of your paper: your evaluation of a specific design pattern.
Please do conduct a second round of reviews
Design Patterns revisited
tisdag 20 oktober 15
Principles + Problem = Pattern
tisdag 20 oktober 15
Principles = SOLID + Some more tips
tisdag 20 oktober 15
Some more tips
• Encapsulate what varies
• Program to an interface not to an implementation
• Favor Composition over Inheritance
• Don’t call us, we’ll call you
tisdag 20 oktober 15
Some more tips
• Depend upon abstractions. Do not depend upon concrete classes.
• Strive for loosely coupled designs between objects that interact
• Only talk to your friends
tisdag 20 oktober 15
Some Design Patterns
tisdag 20 oktober 15
You choose!• Strategy
• Factory Method
• Decorator
• Template Method
• Composite
• Abstract Factory (+ Dependency Injection)
• Singleton (+ example in Ruby)
• Builder
• Adapter
• Bridge
• Observer
• Chain of Responsibility
• Memento
• Command
tisdag 20 oktober 15
Strategy
tisdag 20 oktober 15
StrategyContext
Client
Strategy
tisdag 20 oktober 15
Strategy: Consequences- Clients must be aware
of different strategies
- Communication required between context and strategies
- Potentially many strategy objects created
+Can choose implementation of a strategy at run time
+Eliminate hardcoded conditionals
+Avoids excessive subclassing
tisdag 20 oktober 15
Factory Method
tisdag 20 oktober 15
Factory method (before)
tisdag 20 oktober 15
Factory method (before)
Pizza pizza = null; if (style.equals("NY")) { if (type.equals("cheese")) { pizza = new NYStyleCheesePizza(); } else if (type.equals("veggie")) { pizza = new NYStyleVeggiePizza(); } else if (type.equals("clam")) { pizza = new NYStyleClamPizza(); } else if (type.equals("pepperoni")) { pizza = new NYStylePepperoniPizza(); } } else if (style.equals("Chicago")) { if (type.equals("cheese")) { pizza = new ChicagoStyleCheesePizza(); } else if (type.equals("veggie")) { pizza = new ChicagoStyleVeggiePizza(); } else if (type.equals("clam")) { pizza = new ChicagoStyleClamPizza(); } else if (type.equals("pepperoni")) { pizza = new ChicagoStylePepperoniPizza(); } } else { System.out.println("Error: invalid type of pizza"); return null; }
tisdag 20 oktober 15
Factory method
tisdag 20 oktober 15
Factory method- Requires keeping factory
methods in sync with domain classes
+Decouples clients from specific dependency classes
+Eliminates hardcoded conditionals
+Connects parallel class hierarchies (NY*Pizza, Chicago*Pizza)
tisdag 20 oktober 15
Decorator
tisdag 20 oktober 15
Decorator Beverage b = new Coffee(); b = new SweetenedBeverage(new SweetenedBeverage(b));
return 5+beverage.cost();
Component
Decorator
tisdag 20 oktober 15
Decorator- Decorator objects are
not of the same type as the objects it comprises
- May result in many small objects
+Dynamically adds behavior to specific instances of a class
+Customizes an abstract class without knowing the implementations
tisdag 20 oktober 15
Template Method
tisdag 20 oktober 15
class Coffee{public: void prepareRecipe(); void boilWater(); void brewCoffeeGrinds(); void pourInCup(); void addSugarAndMilk();};
class Tea{public: void prepareRecipe(); void boilWater(); void steepTeaBag(); void pourInCup(); void addLemon();};
class Beverage {public: void prepareRecipe(); void boilWater(); void pourInCup(); };
brew
addCondiments
tisdag 20 oktober 15
Template method: Consequences
+Can isolate the extensions possible to an algorithm
+Isolates clients from algorithm changes
tisdag 20 oktober 15
Template method
tisdag 20 oktober 15
Default implementations
(hooks)public abstract class CaffeineBeverageWithHook { void prepareRecipe() { boilWater(); brew(); pourInCup(); if (customerWantsCondiments()) { addCondiments(); } } boolean customerWantsCondiments() { return true; }
public class CoffeeWithHook extends CaffeineBeverageWithHook { [ ... ] public boolean customerWantsCondiments() { return getUserInput().toLowerCase().startsWith("y"); }}
tisdag 20 oktober 15
Template method?
No
Duck[] ducks = { new Duck("Daffy", 8), new Duck("Dewey", 2), new Duck("Howard", 7), new Duck("Louie", 2), new Duck("Donald", 10), new Duck("Huey", 2) };
Arrays.sort(ducks, new Comparator<Duck>(){
@Override public int compare(Duck arg0, Duck arg1) { return new Integer(arg1.weight).compareTo(arg0.weight); } });
public class Duck implements Comparable<Duck> { String name; int weight; public Duck(String name, int weight) { this.name = name; this.weight = weight; } public String toString() { return MessageFormat.format("{0} weighs {1}", name, weight); } public int compareTo(Duck object) { return new Integer(this.weight).compareTo(object.weight); }}
Yes
tisdag 20 oktober 15
// Java 8: With inline lambda Arrays.sort(ducks, (arg0, arg1) -> new Integer(arg1.weight).compareTo(arg0.weight));
tisdag 20 oktober 15
Composite
tisdag 20 oktober 15
Breakfast menu
Coffee menu
Ham & eggs
Spam & eggs
Eggs & spam
Spam, spam &
eggs
Coffee menu
Dark roast
CoffeeTea Espresso
Pizza menu
Coffee menu
Clam Pizza
Cheese Pizza
Diner menu
Waiter
printMenu()
print()
print()
print()
print()
tisdag 20 oktober 15
Peter, you said that I should respect the SINGLE
RESPONSIBILITY PRINCIPLE. Now you are proposing me a
Composite Pattern with classes with double responsibilities
SRP?
Yes indeed we are intentionally violating the SRP. Actually I�m not violating it; I�m trading it for transparency
• By allowing the Component Interface to contain the child management operations and leaf operations, a client can treat both composite and leaf nodes uniformly
tisdag 20 oktober 15
Client
Component
Composite
Leaf
tisdag 20 oktober 15
Composite: consequences
- Creates composite classes that violate the principle of a single responsibility
- The composite cannot rely on components to implement all methods
+Allow us to treat composite objects and individual objects uniformly
+Allows arbitrarily complex trees
tisdag 20 oktober 15
Abstract factory
tisdag 20 oktober 15
NY
Chicago
Fresh Clam
Mozzarella Cheese
Thin Crust Dough
Frozen ClamParmesan Cheese
Thick Crust Dough
Ingredients
Pizza Store
Pizza Store Clients
I Want a Cheese Pizza
tisdag 20 oktober 15
50
Abstract Factory Example
! Interface toolkit to support multiple look-and-feel standards
tisdag 20 oktober 15
49
The Abstract Factory Template
! Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
tisdag 20 oktober 15
tisdag 20 oktober 15
tisdag 20 oktober 15
tisdag 20 oktober 15
Abstract Products
Abstract Factory
Concrete Factory
tisdag 20 oktober 15
Clients
tisdag 20 oktober 15
Abstract factory: consequences
+Isolates clients from concrete dependencies
+Makes interchanging families of products easier
tisdag 20 oktober 15
Strategy• When related classes only
differ in behavior
• You need different variants of an algorithm
• An algorithm uses data the clients don’t need to know
• A class uses conditionals for selecting behavior
Abstract Factory
• A system should be independent of how its products are created
• A system should be configured with one of multiple families of products
• You want to provide a class library of products, and only expose their interfaces
Behavioral Creational
tisdag 20 oktober 15
Design principles
• Encapsulate what varies
• Program to an interface, not to an implementation
• Favor composition over inheritance
• Classes should be open for extension but closed for modification
• Don’t call us, we’ll call you
tisdag 20 oktober 15
Dependency Injection
tisdag 20 oktober 15
Distinguished by namespaces in C#
-cheeseICheesePizza
<<ICheese>>
MozzarellaCheese ParmesanCheese
<<IClam>>
FreshClam FrozenClam
-cheese-clam
IClamPizza
FancyClamPizza
StandardCheesePizza
NYStyle ChicagoStyle
tisdag 20 oktober 15
1. Declare dependencies as constructor arguments of interface types
2. Register classes (components) in an Inversion-of-Control Container
3. Resolve the top-level object from an interface through the Container
DI: How?
tisdag 20 oktober 15
1. Dependencies
namespace DITest{! public class FancyClamPizza: IClamPizza! {! ! private IClam clam;! ! private ICheese cheese;
! ! public FancyClamPizza (IClam clam, ICheese cheese)! ! {! ! ! this.clam = clam;! ! ! this.cheese = cheese;! ! }
! ! public String ClamType() {! ! ! return String.Format("fancy {0}",clam);! ! }
! ! public String Describe() {! ! ! return String.Format("fancy clam pizza with {0} and {1}",ClamType(), cheese);! ! }! }}
tisdag 20 oktober 15
2. Registrationnamespace DITest{! public class IoCInstaller: IWindsorInstaller! {! ! public void Install(IWindsorContainer container, IConfigurationStore store)! ! {! ! ! container.Register(Classes! ! ! .FromThisAssembly()! ! ! .InNamespace("DITest.NYStyle")! ! ! .WithServiceAllInterfaces());! ! ! container.Register (Classes! ! ! .FromThisAssembly()! ! ! .AllowMultipleMatches()! ! ! .InSameNamespaceAs<IoCInstaller>()! ! ! .WithServiceAllInterfaces());! ! }! }}
Castle Windsor, http://www.castleproject.org
tisdag 20 oktober 15
3. Resolution
! ! ! var container = new WindsorContainer();! ! ! // adds and configures all components using WindsorInstallers from executing assembly! ! ! container.Install(FromAssembly.This());
! ! ! // instantiate and configure root component and all its dependencies and their dependencies and...
! ! ! var p = container.Resolve<ICheesePizza>();! ! ! Console.WriteLine (p.Describe ());
tisdag 20 oktober 15
Singleton
tisdag 20 oktober 15
public class Singleton {
private static Singleton instance = new Singleton();
private String name;
public String getName() { return name; }
private Singleton() { [ ... ] }
}
Our app takes forever to load
public static void someOtherMethod(){ System.out.println("Hi there!"); }
What about static methods?
private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }
tisdag 20 oktober 15
Thread t1 = new Thread(new StaticMethodInvocation()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }
someOtherMethod invokedSingleton name: AndersSingleton lookup took 1 003 348 000 nsStatic method invocation took 1 002 463 000 ns
tisdag 20 oktober 15
private static Singleton instance; public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
How about now?
someOtherMethod invokedStatic method invocation took 899 000 nsSingleton name: AndersSingleton lookup took 1 002 277 000 ns
tisdag 20 oktober 15
What about threads?
tisdag 20 oktober 15
private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }
private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } }
public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); }
Singleton name: AndersSingleton name: JonasSingleton name after our threads have run: Anders
Oops!
tisdag 20 oktober 15
Singleton name: AndersSingleton name: AndersSingleton lookup took 1 003 340 000 nsSingleton lookup took 1 003 286 000 nsSingleton name after our threads have run: Anders
public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }
Woohoo!
tisdag 20 oktober 15
Singleton as Enumpublic enum EnumSingleton {
INSTANCE; private String name; private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
tisdag 20 oktober 15
Singletons in Ruby
Class
MetaClass
A
A
Object
foo
Singleton Class for foo class << foo; end
class A; end
foo = A.new class A; end
Singleton Class for A class << A; end
tisdag 20 oktober 15
class A
end
a = A.new
class << A
def new raise "Illegal!" end
end
irb(main):014:0> a#<A:0x007f8d6b92bcb0>irb(main):016:0> A.newRuntimeError: Illegal! from (irb):10:in `new' from (irb):16 from /Users/olale/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'
Now we have one object, but we cannot produce another of the same class
tisdag 20 oktober 15
Singleton: consequences
- Violates several design principles!
+Ensures single objects per class
tisdag 20 oktober 15
Singleton considered dangerous
• Encapsulate what varies
• Program to an interface, not to an implementation
• Favor composition over inheritance
• Classes should be open for extension but closed for modification
• Don’t call us, we’ll call you
• Depend on abstractions, do not depend on concrete classes
• Classes should only have one reason to change
• Strive for loosely-coupled designtisdag 20 oktober 15
Builder
tisdag 20 oktober 15
9 TDDB82 Design Patterns HT1 2009 LECTURE 05
Builder – Non Software Example
tisdag 20 oktober 15
Client Director Builder
build()buildA()
buildB()
buildC()
getProduct()
tisdag 20 oktober 15
10
The Builder Design Pattern
The client creates the Director object and configures it with the desired Builder object. Director notifies the builder whenever a part of the product should be built. Builder handles requests from the director and adds parts to the product. The client retrieves the product from the builder.
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
tisdag 20 oktober 15
Director
Client
Builder
tisdag 20 oktober 15
Client requests a product from Factory
Client receives a Factory
Client receives an abstract product
Abstract Factory
Client asks Director to build
Client receives a builder-specific product
Client initializes Director with Builder
Client requests product from Builder
Builder
tisdag 20 oktober 15
Builder: consequences- Not necessarily a
common interface for products
- Clients must know how to initialize builders and retrieve products
+Can control the way objects are created
+Can produce different products using the same Director
tisdag 20 oktober 15
Adapter
tisdag 20 oktober 15
11
Class Adapter
! A class adapter uses multiple inheritance to adapt one interface to another
12
Object Adapter
! An object adapter relies on object composition
Class Adapter
Object Adapter
tisdag 20 oktober 15
Multiple back-end objects
Client do()Target
+perform()Adaptee1
do()
-adaptee1-adaptee2
Adapter
+perform()Adaptee2
tisdag 20 oktober 15
Multiple back-end methods
Client do()Target
+foo()+bar()
Adaptee1
do()-adapteeAdapter
adaptee.foo()adaptee.bar()
tisdag 20 oktober 15
public interface Duck { public void quack(); public void fly();}
public interface Turkey { public void gobble(); public void fly();}
public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } public void quack() { turkey.gobble(); } public void fly() { for(int i=0; i < 5; i++) { turkey.fly(); } }}
public class DuckAdapter implements Turkey { Duck duck; Random rand; public DuckAdapter(Duck duck) { this.duck = duck; rand = new Random(); } public void gobble() { duck.quack(); } public void fly() { if (rand.nextInt(5) == 0) { duck.fly(); } }}
tisdag 20 oktober 15
Adapter: consequences- Class adapters require
target interfaces or multiple inheritance in the language
+Isolates interface changes to the adapter class
tisdag 20 oktober 15
Bridge
tisdag 20 oktober 15
20
The Bridge Pattern Structure
Abstraction == That which we (should) care about
tisdag 20 oktober 15
Samsung LG
Logitech Harmony
On()Off()
On()Off()
One For All On()Off()
On() Off()
TV
Remote
tisdag 20 oktober 15
Password recovery
Signup
E-mail Send() Send()
SMS Send() Send()
Message type
Transmission type
tisdag 20 oktober 15
Bridge Strategy
Intent
Collaborations
Decouple two class hierarchies
(abstraction/implementation)
Allow for exchangeable
algorithms
The Bridge forwards requests to the Implementor
The Context and Strategy
collaborate, passing data between them
tisdag 20 oktober 15
Bridge Adapter
Intent
Applicability
Decouple two class hierarchies
(abstraction/implementation)
Convert an existing class to fit a new
interface
In a new system In an existing system
tisdag 20 oktober 15
Design principles• Encapsulate what varies
• Program to an interface, not to an implementation
• Favor composition over inheritance
• Classes should be open for extension but closed for modification
• Don’t call us, we’ll call you
• Depend on abstractions, do not depend on concrete classes
• Classes should only have one reason to change
tisdag 20 oktober 15
Bridge: consequences- If some implementation
classes do not support an abstract concept, the abstraction breaks
+Lets two class hierarchies with common superclasses vary independently
tisdag 20 oktober 15
Observer
tisdag 20 oktober 15
tisdag 20 oktober 15
Weather Station Humidity Display Average Temp Display
subscribe()
subscribe()
publish()
publish()
unsubscribe()
publish()
tisdag 20 oktober 15
35
Loose Coupling
! The only things the subject knows about an observer is that it implements a certain interface
! We can add new observers at any time ! We never need to modify the subject to add new types of
observers ! We can reuse subjects or observers independently of each
other ! Changes to either the subject or an observer will not affect
the other
tisdag 20 oktober 15
Subject Concrete Observer
tisdag 20 oktober 15
Mediator vs
Observer
tisdag 20 oktober 15
Design principles• Encapsulate what varies
• Program to an interface, not to an implementation
• Favor composition over inheritance
• Classes should be open for extension but closed for modification
• Don’t call us, we’ll call you
• Depend on abstractions, do not depend on concrete classes
• Classes should only have one reason to change
• Strive for loosely-coupled designtisdag 20 oktober 15
Chain of Responsibility
tisdag 20 oktober 15
SPAM FilterisSpam(Message)
Message rejected
reject
Size FilterisTooLarge(Message)accept
reject
Sorting Filtersort(Message)accept process
Message arrived
tisdag 20 oktober 15
47
Chain of Responsibility Structure
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. tisdag 20 oktober 15
Examples
• Logging
• Input management in GUI:s
tisdag 20 oktober 15
CoR: consequences- A handler does not
know if it will receive a message, depending on the behavior of other handlers in the chain
+provides the Observer with more control over invocation of targets
tisdag 20 oktober 15
Memento
tisdag 20 oktober 15
TDDB84 Design Patterns Slide 3
The Memento – Non Software Example
! This pattern is common among do-it-yourself mechanics repairing drum brakes on their cars. The drums are removed from both sides, exposing both the right and left brakes .
! Only one side is disassembled, and the other side serves as a Memento of how the brake parts fit together
! Only after the job has been completed on one side is the other side disassembled. When the second side is disassembled, the first side acts as the Memento
The Memento captures and externalizes an object's internal state, so the object can be restored to that state later.
tisdag 20 oktober 15
Optimize()Abort()GetState()SetState()
iterationcurrent target valuecurrent solution
Iterative Optimizer
Optimize()Abort()ResetOptimizer(SolverMemento)
- memento- optimizer
Client
iterationcurrent target valuecurrent solution
SolverMemento
tisdag 20 oktober 15
TDDB84 Design Patterns Slide 4
Memento
Originator o = new Originator(); o.state = "On"; // Store internal state Caretaker c = new Caretaker(); c.memento = o.CreateMemento(); // Continue changing originator o.State = "Off"; // Restore saved state o.SetMemento( c.Memento );
tisdag 20 oktober 15
Mementos in GUI:s - Undo/Redo
giUser Name
GinnieAge24
1
gijo
User Name
Ginnie
Johnny
Age
24
372
giUser Name
GinnieAge24
4
UndoRedo
CutCopyPastePaste special...
DeleteSelect All
3
tisdag 20 oktober 15
Memento: consequences
- Depending on implementation, access to private fields requires memento classes as inner/friend classes to each domain class
+Can externalize object state for later restoration within the lifetime of the object
+Encapsulates access to the objects’ inner state
tisdag 20 oktober 15
Command
tisdag 20 oktober 15
Client Waiter Order Chef
Place Order
Cook
Order
Command
tisdag 20 oktober 15
Remote control
TDDB84 Design Patterns Slide 30
The Ultimate Remote Control
Joe’s Ultimate Remote Control
On Off
On Off
On Off
On Off
On Off
On Off
On Off
Undo
High()Low()Off()GetSpeed()
Fan
TurnOn()TurnOff()SetChannel()
TV
On()Off()Dim()
Lamp
tisdag 20 oktober 15
Client
perform()-command
Invoker+execute()
Command
+perform()Receiver
-receiver
Concrete Command
tisdag 20 oktober 15
Invoker
Invoker
Client
Concrete Commands
Command
Receiver
tisdag 20 oktober 15
Command: consequences
+Allows extensions of commands
+Decouples the execution from the specification of the command
- Bad design if not needed!
- May be confusing if it removes the receiver from responsibilities
tisdag 20 oktober 15
Course summary
• Practical work:
• Intro seminar + three labs
• Reflection and analysis:
• Reading a research paper, and studying design patterns in a real context
tisdag 20 oktober 15
Life after the course
• Writing your papers :)
• Masters theses: Info @ 12:15!
• Research project in Software Engineering
• Exam? No.
tisdag 20 oktober 15
Thanks for your participation, and good luck with your papers!
tisdag 20 oktober 15