• Design Patterns II Gang of Four Pattern Catalog

Design Patterns • II
Design Patterns • II
Alexei Khorev
Alexei Khorev
Design Patterns • II
Gang of Four Pattern Catalog
Erich Gamma on Design Patterns
1 Software DPs
Software DPs
The Design Pattern
Bible
COMP2110/2510
Software Design
Software Design for SE
September 10, 2008
Software DPs
The Design Pattern
Bible
JUnit case study
JUnit case study
2 The Design Pattern Bible
GoF Catalog
GoF Catalog
3 JUnit case study
4 GoF Catalog
Alexei Khorev
Department of Computer Science
The Australian National University
16.1
Refresh DP’s definition
Design Patterns • II
16.2
What the Design pattern is?
Alexei Khorev
Design Patterns • II
Alexei Khorev
Software DPs
• A design pattern is a way of reusing abstract knowledge
The Design Pattern
Bible
about a problem and its solution
JUnit case study
• A pattern is a description of the problem and the essence of
GoF Catalog
its solution
According to Buschmann et al, “PatternOriented Software Architecture”, Wiley 1996:
• A pattern is a reusable abstraction which can be applied in
“ A pattern for software architecture describes a particular
recurring design problem that arises in specific design contexts and
presents a well-proven generic scheme for its solution. The
solution scheme is specified by describing its constituent
components, their responsibilities and relationships, and the ways
in which they collaborate.”
• A pattern is the abstraction from a concrete form which keeps
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
different settings
recurring in specific non-arbitrary contexts
• Pattern is an abstraction which goes beyond object
characteristics such as inheritance and polymorphism, and
often relies on them
16.3
16.4
What the Design pattern does?
Design Patterns • II
Design patterns characteristics
Alexei Khorev
• A design pattern represents a widely accepted solution to a
recurring design problem in OOP
• A design pattern describes how to structure classes to meet a
given requirement
Design Patterns • II
Alexei Khorev
•
A pattern describes a solution to a recurring problem that arises in specific design
situations
•
•
Patterns are not invented; they are distilled from practical experience
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
• A design pattern provides a general blueprint to follow when
implementing part of a program
• A design pattern does not describe how to structure the entire
application
Patterns describe a group of components (eg, classes or objects), how the components
interact, and the responsibilities of each component. That is, they are higher level
abstractions than classes or objects
•
Patterns provide a vocabulary for communication among designers. The choice of a
name for a pattern is very important
•
Patterns help document the architectural vision of a design. If the vision is clearly
understood, it will less likely be violated when the system is modified
•
Patterns provide a conceptual skeleton for a solution to a design problem and, hence,
encourage the construction of software with well-defined properties
•
Patterns are building blocks for the construction of more complex designs
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
• A design pattern does not describe specific algorithms
Patterns help designers manage the complexity of the software. When a
recurring pattern is identified, the corresponding general solution can be
implemented productively to provide a reliable software system.
• A design pattern focuses on relationships between classes
16.5
The Gang-Of-Four Book
Design Patterns • II
16.6
Facts about the GoF book
Alexei Khorev
The adoption and efficient use of a new technology benefits
greatly from a systematic and high quality description of such
technology.
In the case of DPs, the incontestable source of their description is
the famous book:
Design Patterns • II
Alexei Khorev
• The authors worked on it over four years, selecting OO
design practices which could be recast as design patterns,
distilling the presentation, culling those deemed not immature
yet etc. The result:
Software DPs
The Design Pattern
Bible
JUnit case study
Software DPs
The Design Pattern
Bible
JUnit case study
• One of the top bestselling books on software — fourteen
GoF Catalog
GoF Catalog
years on, it’s reprinted 3-4 times a year, more than half a
million copies have been sold so far. People are eagerly
waiting for a new edition. . .
Author
Erich Gamma, Richard Helm,
Ralph Johnson, and John Vlissides
• Printed T-shirts with individual DPs can be
Title
purchased from Coder Gear Company —
choose your favourite design pattern today!
• A CD version of the book is also available
(very handy!)
• Now, Amazon does not only sell the book, but also provide an
on-line copy for reading (akin to Google Books service)
Design Patterns: Elements of
Reusable Object-Oriented Software
Publisher
Addison–Wesley
Year
1995
16.7
16.8
Erich Gamma on GoF experience
Design Patterns • II
Pattern-driven design: JUnit framework
Alexei Khorev
Erich Gamma gave a series of interview
to Aritma Developer on-line magazine in
which he offered a valuable advice on the
practice of design pattern. Here are some
quotes:
“You have to feel the pain of a design which has some problem. [Only then]
you. . . appreciate a pattern. Like realizing your design isn’t flexible enough, a
single change ripples through the entire system, you have to duplicate code, or
the code is just getting more and complex. If you then apply a pattern in such a
messy situation it can happen that the pain goes away and you feel good
afterwards. It’s an eye opener to realize that oh, actually this pattern, factory
or strategy, is a solution to my problem.”
Design Patterns • II
Alexei Khorev
The famous testing framework JUnit was first developed by Kent
Beck and E. Gamma during a trans-atlantic flight in 1997. The
circumstances of this feat (“Never software industry owed so much
to so fewer lines of code”) is the testimony of the great
communicative benefits which DPs bring into software
development:
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
Kent and I were fluent in patterns when we designed JUnit. So of course, we’d
say things like, "Hey, that’s composite." Composite is a pattern in JUnit. We
also use template method. That’s a basic one. We have command. This is of
course a key one. We started with test and said, "Oh, this is a command. Oh,
this is a template." Because we were fluent in patterns, our conversation was
going really fast, enabling a high-velocity design.” [The high-velocity design means
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
just that — over six-seven hours at the high altitude.]
“Do not start immediately throwing patterns into a design, but use them as you
go and understand more of the problem.” (“20 out 23” case)
On the difference with Alexander’s pattern language approach to design:
“. . . when you follow Alexander’s patterns approach you follow the patterns in
some sequence. We don’t prescribe a particular order. If you have a problem, we
have the solution for that, but we don’t have the next step. We don’t give you
hints on what to do next. Alexander is way more thorough in this regard.”
“These days software is too complex. We can’t afford to speculate what else it
should do. We need to really focus on what it needs. That’s why I like
refactoring to patterns.”
16.9
Design of JUnit
Design Patterns • II
16.10
JUnit Design – TestCase, Command
Alexei Khorev
Design Patterns • II
Alexei Khorev
The core of the JUnit testing technique is an object of the
TestCase class. Standard testing techniques:
Goals of JUnit (“mission statement”):
• Create facility for automated tests for classes developers write
Software DPs
• It has to be a small (easy to learn) framework (flexible and
adoptable)
• Make created tests to retain their value over time; allow to
Software DPs
The Design Pattern
Bible
• print statements
The Design Pattern
Bible
JUnit case study
• debugger expressions
JUnit case study
GoF Catalog
• test scripts
combine tests and run them independently
GoF Catalog
To make manipulating tests easy, one has to make them objects.
The test object has to execute a testing routine. The Command
pattern deals with creating object for an operation and give it a
method “execute” — this intent fits the goal perfectly.
• Leverage existing tests to create new ones — provide setup
or fixtures for automated selection of tests for run and
creating an appropriate execution environment
Design approach:
public abstract class TestCase implements Test {
private final String fName;
1 start with nothing (skip the SRS, ,)
2 apply patterns, one after another, until you have the
architecture of the system
public TestCase(String name) {
fName = name;
}
3 Refine and refactor the design
public abstract void run()
...
}
16.11
16.12
JUnit Design – run(), Template
Design Patterns • II
Design Patterns • II
JUnit Design – TestResults
Alexei Khorev
Next, one has to define the place to
put the fixture code and the test code
itself. The common structure to all
tests — they set up a test fixture, run
some code against the fixture, check
some results, and then clean up the
fixture.
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
Template Method intent addresses the problem: “Define the
skeleton of an algorithm in an operation, deferring some steps to
subclasses. Template Method lets subclasses redefine certain
steps of an algorithm without changing the algorithm’s structure.”
The developer should to be able to separately consider how to write the fixture (set up and tear
down) code and how to write the testing code. The execution of this sequence, however, will
remain the same for all tests, no matter how the fixture code is written or how the testing code
is written.
Alexei Khorev
After the test has run, one has to
get a summary of what did and
didn’t work. Because tests are
expected to work, we only want
to record the failures and a highly
condensed summary of the successes.
The Smalltalk pattern (but not GoF!), Collecting Parameter, fits the
bill: when you need to collect results over several methods, you
should add a parameter to the method and pass an object that will
collect the results for you. We create a new object, TestResult, to
collect the results of running tests.
public class TestResult {
protected int fRunTests;
public void run() {
setUp();
runTest();
tearDown();
ublic TestResult() {
fRunTests= 0;
}
Software DPs
The Design Pattern
Bible
JUnit case study
GoF Catalog
public void run(TestResult res) {
res.startTest(this);
setUp();
runTest();
tearDown();
}
}
}
For details see JUnit A Cook’s Tour.
16.13
JUnit Design – TestCase, Adapter
Design Patterns • II
16.14
JUnit Design – TestSuite, Composite
Alexei Khorev
We need an interface to generically run our
tests, but all test cases are implemented as different methods in the same class. This avoids
the unnecessary proliferation of classes. A
given test case class may implement many different methods, each defining a single test case.
Each test case has a descriptive name like
testMethod1() etc. The test cases don’t conform to a simple command interface. Different
instances of the same Command class need to
be invoked with different methods. Therefore
our next problem is make all the test cases look
the same from the point of view of the invoker of
the test.
Software DPs
The Design Pattern
Bible
Design Patterns • II
Alexei Khorev
We often need to run many tests. Our next challenge is to extend TestCase to run many
different tests. This problem can be solved easily when the invoker of the tests doesn’t have to
care about whether it runs one or many test cases. A popular pattern to pull out in such a
situation is Composite: “Compose objects into tree structures to represent part-whole
hierarchies. Composite lets clients treat individual objects and compositions of objects
uniformly.”
Software DPs
The Design Pattern
Bible
JUnit case study
JUnit case study
GoF Catalog
GoF Catalog
The Adapter pattern springs to mind: “Convert the interface of a
class into another interface clients expect”. Two implementations
are possible; a shorter one uses anonymous inner classes (this is
an example of an idiom used for the pattern implementation):
The Composite participants:
•
•
•
TestCase test= new MoneyTest("testMethod1") {
protected void runTest() { testMethod1(); }
}
Component: declares the interface we want to use to interact with our tests
Composite: implements this interface and maintains a collection of tests
Leaf: represents a test case in a composition that conforms to the Component interface
Another solution involves the Smalltalk pattern P S, which allows to use a single
class which can be parameterized to perform different logic without requiring subclassing.
16.15
16.16
Design Patterns • II
JUnit Design – the full picture
Now we can put everything together:
JUnit Design – Pattern Driven Design
Alexei Khorev
Alexei Khorev
Let’s repeat the Pattern Driven path of the JUnit design:
Software DPs
Design Patterns • II
Software DPs
The Design Pattern
Bible
The Design Pattern
Bible
JUnit case study
JUnit case study
GoF Catalog
GoF Catalog
Very impressive! But in reality such a streamlined application of
DPs during the design process is rare, and should not be relied
upon.
The JUnit design has very high “pattern density” — the ratio of
DPs used to the number of classes. This is not typical: ordinary
application need not be “pattern-dense”. Frameworks, on the other
hand, usually have higher “pattern density” (and they are more
difficult to design).
16.17
Design Patterns • II
Catalog of Patterns: Three categories
Alexei Khorev
In the following lectures will shall discuss some of the GoF DPs.
Creational
Structural
Software DPs
•
•
•
•
•
Abstract Factory
Factory Method
Builder
Prototype
Singleton
•
•
•
•
•
•
•
Adapter
The Design Pattern
Bible
Bridge
JUnit case study
Composite
GoF Catalog
•
•
•
•
•
Observer
Decorator
Façade
Flyweight
Proxy
Behavioural
•
•
•
•
•
•
Chain of Responsibility
Command
Interpreter
Iterator
Mediator
State
Strategy
Template Method
Visitor
Memento
16.19
16.18