Frameworks are general code libraries that developers use to build their software on. Frameworks are usually specific to a domain, like web frameworks or database frameworks. The benefit of frameworks is the productivity that they provide. With the right framework we can avoid writing low-level functionality and instead focus on our domain problems we need to solve. Frameworks are building blocks and should be used as such, if you have a bad framework or need to invest too much into using the framework, the gains are counter productive.
It may be a good strategy to write your own framework, and in the lecture we look at design patterns that are useful in creating frameworks. We will also look at the Spring framework that is a good example of a well design framework.
Cover image by Javier Corbo
http://www.flickr.com/photos/javiercorbo/
2. Agenda
Why frameworks?
Framework patterns
– Inversion of Control and Dependency Injection
– Template Method
– Strategy
From problems to patterns
– Game Framework
Spring framework
– Bean containers
– BeanFactory and ApplicationContext
3. Reading
Dependency Injection
Template Method Pattern
Strategy Pattern
Spring Framework (video)
Article by Fowler
– Inversion of Control Containers and the Dependency
Injection pattern
4. Resources
Spring Framework homepage
– http://www.springframework.org
Reference Documentation
– http://www.springframework.org/docs/reference/index.
html
– Also in PDF format
6. Why use Frameworks?
Frameworks can increase productivity
– We can create our own framework
– We can use some third party framework
Frameworks implement general functionality
– We use the framework to implement our business
logic
7. Framework design
Inheritance of framework classes
Composition of framework classes
Implementation of framework interfaces
Dependency Injection
Framework
Your Code
Domain ?
8. Using Frameworks
Frameworks are concrete, not abstract
– Design patterns are conceptual, frameworks provide
building blocks
Frameworks are higher-level
– Built on design patterns
Frameworks are usually general or technology-
specific
Good frameworks are simple to use, yet
powerful
9. Abstractions
From API to Frameworks
API Definition JEE/.NET API
API Patterns JEE/.NET
Patterns
Framework Spring
10. Open Source Frameworks
Web Frameworks
– Jakarta Struts, WebWork, Maverick, Play!
Database Frameworks
– Hibernate, JDO, TopLink
General Framework
– Spring, Expresso, PicoContainer, Avalon
Platform Frameworks
– JEE
11. Where do Frameworks Come
From?
Who spends their time writing frameworks?
If they give them away, how can anyone make
money?
Companies that use frameworks, have their
developers work on them
Give the code, sell the training and consulting
12. Write down the pros and cons (benefits and drawbacks) for frameworks.
Use two columns, benefits on the left, drawbacks right
EXERCISE
13. Pros and Cons
Pros
– Productivity
– Well know application
models and patterns
– Tested functionality
– Connection of different
components
– Use of open standards
Cons
– Can be complicated,
learning curve
– Dependant on frameworks,
difficult to change
– Difficult to debug and find
bugs
– Performance problems can
be difficult
– Can be bought by an evil
company
15. Separation of Concerns
One of the main challenge of frameworks is to
provide separation of concerns
– Frameworks deal with generic functionality
– Layers of code
Frameworks need patterns to combine generic and
domain specific functionality
16. Framework Patterns
Useful patterns when building a framework:
– Dependency Injection: remove dependencies by
injecting them (sometimes called Inversion of Control)
– Template Method: extend a generic class and provide
specific functionality
– Strategy: Implement an interface to provide specific
functionality
17. Dependency Injection
Removes explicit dependence on specific
application code by injecting depending classes
into the framework
Objects and interfaces are injected into the
classes that to the work
Two types of injection
– Setter injection: using set methods
– Constructor injection: using constructors
18. Dependency Injection
Fowler’s Naive Example
– MovieLister uses a finder class
– How can we separate the finder functionality?
class MovieLister...
public Movie[] moviesDirectedBy(String arg) {
List allMovies = finder.findAll();
for (Iterator it = allMovies.iterator(); it.hasNext();) {
Movie movie = (Movie) it.next();
if (!movie.getDirector().equals(arg)) it.remove();
}
return (Movie[])allMovies.toArray(new Movie[allMovies.size()]);
}
Separate what varies
REMEMBER PROGRAM TO INTERFACES PRINSIPLE?
19. Dependency Injection
Fowler’s Naive Example
– Let’s make an interface, MovieFinder
– MovieLister is still dependent on particular
MovieFinder implementation
public interface MovieFinder {
List findAll();
}
class MovieLister...
private MovieFinder finder;
public MovieLister() {
finder = new MovieFinderImpl("movies1.txt");
}
Argh!
Not cool.
20. Dependency Injection
An assembler (or container) is used to create an
implementation
– Using constructor injection, the assember will create a
MovieLister and passing a MovieFinder interface in the
contructor
– Using setter injection, the assembler will create
MovieLister and then all the setFinder setter
method to provide the
MovieFinder interface
21. Dependency Injection
Example setter injection
class MovieLister...
private MovieFinder finder;
public void setFinder(MovieFinder finder) {
this.finder = finder;
}
class MovieFinderImpl...
public void setFilename(String filename)
this.filename = filename;
}
28. Template Method Pattern
Create a template for steps of an algorithm and let
subclasses extend to provide specific
functionality
We know the steps in an algorithm and the order
– We don’t know specific functionality
How it works
– Create an abstract superclass that can be extended
for the specific functionality
– Superclass will call the abstract methods when
needed
30. Template Method Pattern
public class AbstractOrderEJB
{
public final Invoice placeOrder(int customerId,
InvoiceItem[] items)
throws NoSuchCustomerException, SpendingLimitViolation
{
int total = 0;
for (int i=0; i < items.length; i++)
{
total += getItemPrice(items[i]) * items[i].getQuantity();
}
if (total >getSpendingLimit(customerId))
{
...
}
else if (total > DISCOUNT_THRESHOLD) ...
int invoiceId = placeOrder(customerId, total, items);
...
}
}
32. Template Method Pattern
public class MyOrderEJB extends AbstractOrderEJB
{
...
int getItemPrice(int[] i)
{
...
}
int getSpendingLimit(int customerId)
{
...
}
int placeOrder(int customerId, int total, int items)
{
...
}
}
33. Template Method Pattern
When to Use it
– For processes where steps are know but some steps
need to be changed
– Works if same team is doing the abstract and the
concrete class
When Not to Use it
– The concrete class is forced to inherit, limits
possibilities
– Developer of the concrete class must understand the
abstract calls
– If another team is doing the concrete class as this
34. Strategy Pattern
Create a template for the steps of an algorithm
and inject the specific functionality
Implement an interface to provide specific
functionality
– Algorithms can be selected on-the-fly at runtime
depending on conditions
– Similar as Template Method but uses interface
inheritance
35. Strategy Pattern
How it works
– Create an interface to use in the generic algorithm
– Implementation of the interface provides the specific
functionality
– Framework class has reference to the interface an
– Setter method for the interface
37. Strategy Pattern
Interface for specific functionality
Generic class uses the interface
– Set method to inject the interface
public interface DataHelper
{
int getItemPrice(InvoiceItem item);
int getSpendingLimit(CustomerId) throws NoSuchCustomerException;
int palceOrder(int customerId, int total, InvoiceItem[] items);
}
private DataHelper dataHelper;
public void setDataHelper(DataHelper newDataHelper)
{
this.dataHelper = newDataHelper;
}
DEPENDENCY INJECTION
38. Strategy Pattern
public class OrderEJB
{
public final Invoice placeOrder(int customerId, InvoiceItem[] items)
throws NoSuchCustomerException, SpendingLimitViolation
{
int total = 0;
for (int i=0; i < items.length; i++)
{
total += this.dataHelper.getItemPrice(items[i]) *
items[i].getQuantity();
}
if (total >this.dataHelper.getSpendingLimit(customerId))
{...
}
else if (total > DISCOUNT_THRESHOLD) ...
int invoiceId = this.dataHelper.placeOrder(customerId,
total, items);
...
}
}
39. We are building framework for games. It turns out that all the games
are similar so we create an abstract class for basic functionality that
does not change, and then extend that class for each game. What
pattern is this?
A) Layered Supertype
B) Template Method
C) Strategy
D) Dependency Injection
QUIZ
✔
41. Framework design
Inheritance of framework classes
Template Method – class Inheritance
Composition of framework classes
Strategy – interface Inheritance
Dependency Injection
Framework
Your Code
Domain ?
42. From Problem to Pattern
We need to design game software
Common turn-based board games like monopoly,
chess, backgammon, yatzy etc.
You must propose a design
43. From Problem to Pattern
Let’s make a Game Framework
What patterns can we use?
44. Patterns
Template Method
– Template of an algorithm
– Based on class inheritance
Strategy
– Composition of an strategy
– Based on interface inheritance
45. Template Method Pattern
Create a template for steps of an algorithm and let
subclasses extend to provide specific
functionality
We know the steps in an algorithm and the order
– We don’t know specific functionality
How it works
– Create an abstract superclass that can be extended
for the specific functionality
– Superclass will call the abstract methods when
needed
46. What is the game algorithm?
initialize
while more plays
make one turn
print winnner
void initializeGame();
boolean endOfGame();
void makePlay(int player);
void printWinner();
49. Interface for game algorithm
package is.ru.honn.game.framework;
public interface Game
{
public void initializeGame();
public void makePlay(int player);
public boolean endOfGame();
public void printWinner();
}
50. The Template
package is.ru.honn.game.framework;
public abstract class AbstractGame implements Game
{
protected int playersCount;
public final void playOneGame(int playersCount)
{
this.playersCount = playersCount;
initializeGame();
int j = 0;
while (!endOfGame()) {
makePlay(j);
j = (j + 1) % playersCount;
}
printWinner();
}
}
51. The Specific Game
class Chess extends AbstractGame
{
public void initializeGame()
{
// Initialize players, put the pieces on the board
}
public void makePlay(int player)
{
// Process a turn for the player
}
public boolean endOfGame()
{
// Return true if in Checkmate or stalemate
return true;
}
public void printWinner()
{
// Display the winning player
}
}
54. Strategy Pattern
Create a template for the steps of an algorithm
and inject the specific functionality (strategy)
Implement an interface to provide specific
functionality
– Algorithms can be selected on-the-fly at runtime
depending on conditions
– Similar as Template Method but uses interface
inheritance
59. The Specific Strategy
class ChessStrategy implements GameStrategy
{
public void initializeGame()
{
// Initialize players, put the pieces on the board
}
public void makePlay(int player)
{
// Process a turn for the player
}
public boolean endOfGame()
{
// Return true if in Checkmate or stalemate
return true;
}
public void printWinner()
{
// Display the winning player
}
}
60. The Context
public class GamePlay
{
GameStrategy strategy;
protected int playersCount;
public void setStrategy(GameStrategy strategy)
{
this.strategy = strategy;
}
public final void playOneGame(int playersCount)
{
this.playersCount = playersCount;
this.strategy.initializeGame();
int j = 0;
while (!this.strategy.endOfGame()) {
this.strategy.makePlay(j);
j = (j + 1) % playersCount;
}
this.strategy.printWinner();
}
}
Polymorphism
61. The Assembler
GamePlay play = new GamePlay();
// Assign the right strategy
play.setStrategy(new ChessStrategy());
What design pattern is used
when the strategy is assigned
to the context?
62. Dependency Injection
Removes explicit dependence on specific
application code by injecting depending classes
into the framework
Objects and interfaces are injected into the
classes that to the work
Two types of injection
– Setter injection: using set methods
– Constructor injection: using constructors
65. Lightweight Containers
Assemble components from different projects
into a cohesive application
– Wiring is done with “Inversion of Control”
– Provide life-cycle management of objects
– Provide context
68. Spring Containers
Lightweight containers
– Provides life-cycle management and other services
BeanFactory
– Simple factory interface for creating beans
ApplicationContext
– Extends BeanFactory and adds some functionality for
application context
Packages
– org.springframework.beans
– org.springframework.context
– Refer to Spring 3
70. Using BeanFactory
BeanFactory
<beans>
<bean id="person" class="Person">
<property name="name">
<value>Olafur Andri</value>
</property>
<property name="email">
<value>andri@ru.is</value>
</property>
</bean>
</beans>
read, parse
create
Person
The Bean Factory uses
setter injection to create the
person object
71. FileSystemXmlApplicationContext
Loads the context from an XML file
Application contexts are intended as central
registries
– Support of hierarchical contexts (nested)
public class AppTest
{
public static void main(String[] args)
{
ApplicationContext ctx =
new FileSystemXmlApplicationContext("app.xml");
}
}
72. Summary
Framework patterns
– Inversion of Control and Dependency Injection
– Template Method
– Strategy
From problems to patterns
– Game Framework
Spring framework
– Bean containers
– BeanFactory and ApplicationContext