Title: Design Patterns
1CSC 335 Object-Oriented Programming and Design
Design Patterns Some Background Consider What
changes Example System using several Patterns
2Patterns A definition
- A pattern is a solution to a problem in a context
- 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.
3OOPSLA 96 Alexander PicDoug Lea quote
- "Alexander's central premise, driving over thirty
years of thoughts, actions, and writings, is
that there is something fundamentally wrong with
twentieth century architectural design methods
and practices. ... Alexander illustrates failures
in the sensitivity of contemporary methods to the
actual requirements and conditions surrounding
their development. He argues that contemporary
methods fail to generate products that satisfy
the true requirements placed upon them by
individuals and society, and fail to meet the
real demands of real users, and ultimately fail
in the basic requirement that design and
engineering improve the human condition."
4Alexander"Quality without a name" Quote from
Dick Gabriel (Sun Fellow)
- "Its modules and abstractions are not too big. If
they were too big, their size and inflexibility
would have created forces that would over govern
the overall structure of the software every
module, function, class, and abstraction is small
and named so that I know what it is without
looking at its implementation. - If I look at any small part of it, I can see what
is going on, I don't need to refer to other parts
to understand what something is doing. This tells
me that the abstractions make sense for
themselves -- they are whole. - If I look at any large part in overview, I can
see what is going on, I don't need to know all
the details to get it. - Everything about it seems familiar.
- I can imagine changing it, adding some
functionality. - I am not afraid of it, I will remember it."
5OO Design Patterns
- Patterns are not invented
- Patterns are "hatched" from software that already
existed 23 OO Patterns are listed inside our
book's cover - These are the similarities found in the design of
software viewed to be of high quality - They made a rule to list three different systems
that solved a problem in the same manner - Thousands of patterns have been documented since
- telecommunications patterns, pedagogical
patterns, analysis patterns, indexing patterns
6What a pattern has
- Formats of pattern writers vary, but a pattern
usually has at least these four things - A name (Iterator, Strategy, Observer, Composite)
- The purpose of the pattern, the problem it solves
- A guide for how to accomplish the solution
- The constraints and forces to be considered in
order to accomplish the solution
7Why Study Patterns?
- Can reuse solutions
- gives us a head start
- avoids the gotchas later (unanticipated things)
- no need to reinvent the wheel
- Establish common terminology
- Design patterns provide a common point of
reference - Easier to say, "We need some Strategies here"
- Provide a higher level prospective
- frees us from dealing with the details too early
8Carpenter's ConversationAdapted from Ralph
Johnson
- How should we build the cabinet drawers?
- Cut straight down into the wood, cut back up 45
degrees a specific length, then go straight back
down a specific length, the cut back up at 45
degrees until you reach, .....
9A Higher Level Discussion
- A high level discussion could have been
- "Should we use a miter joint or a dovetail
joint?" - This is a higher, more abstract level
- Avoids getting bogged down in details
- Which level of detail is more efficient?
10Consequences of which joint
- Dovetail joints
- are more complex, more expensive to make
- withstands climate conditions dovetail joint
remains solid as wood contracts and expands - independent of fastening system
- more pleasing to look at
- Thoughts underneath this question are
- Should we make a beautiful durable joint or a
cheap and dirty one that lasts until the check
clears?
11Consequences
- Carpenters, patterns writers, and software
developers discuss consequences - consequences simply refer to cause and effect
- If we do this, what will happen both good and
bad - also known as the forces that patterns consider
- Example If we use Mediator to add and drop
courses - Add an extra class that needs reference to
several objects - All of the logic and process is confined to one
class so any change to the "rules" would be
handled there - Reduces dependencies between others objects
(simpler design when student does NOT tell the
scheduled course to change)
12Other advantages
- Most design patterns make software more
modifiable, less brittle - we are using time tested solutions
- Helps increase the understanding of basic
object-oriented design principles - encapsulation, inheritance, interfaces,
polymorphism - Designs of large systems can avoid large
inheritance hierarchies (there are alternatives) - learned the hard way about big inheritance
hierarchies
13Example Pattern Iterator
- Name Iterator (a.k.a Enumeration)
- Problem How can you loop over all objects in any
collection. You dont want to change client code
when the collection changes. You also want the
same interface (methods) - Solutions 1) Have each of your classes implement
an interface. 2) Have an Iterator interface that
works with all collections - Consequences Can change collection class without
changing code to traverse the collection
14Java version of Iterator
- interface Iterator
- boolean hasNext()
- Returns true if the iteration has more elements.
- Object next()
- Returns the next element in the iteration
15UML Diagram of Java's Iterator and List interface
List iterator()
Iterator hasNext() next()
Vector iterator()
LinkedList iterator()
ArrayList iterator()
Iterator hasNext() next()
Context
16CSC 335 Object-Oriented Programming and Design
Pattern-Oriented Design by Rick Mercer based on
the GoF book and Design Patterns Explained A New
Perspective on Object-Oriented Design Alan
Shalloway, James R. Trott Addison Wesley ISBN
0-201-71594-5
17Using Patterns to Design
- There are 23 Object-Oriented Design Patterns
cataloged in the GoF book (weve considered
four) - Iterator, Strategy, Factory, Observer
- We'll now use some of these patterns to help
design a system, and see a new one - The new case study is in electronic retailing
over the internet (An Ecommerce system) - Several design decisions will be aided by
knowledge of existing design patterns - at a fairly high level of abstraction
18Plan too much, plan ahead, or dont plan at all?
- Development of software systems can suffer from
analysis paralysis attempt to consider all
possible changes in the future - At other times developers jump to code too
quickly - there is tremendous pressure to deliver, not
maintain - Lifes three certainties for software developers
- Death, Taxes, and Changes in Requirements
- There is a middle ground for planning for change
19How will change occur
- First, anticipate that changes will occur
- Consider where they will change, rather than the
exact nature of the changes - These issues will come up in the Ecommerce case
study
20Principles of Good Design
- Program to an interface, not an implementation
- Use interfaces rather than concrete classes
- Clients remain unaware of the classes of objects
they usethey do adhere to the interface - This reduces implementation dependencies between
subsystems - Then use interface names, not class names
21Dependency Inversion Principle
22Composition
- Favor object composition over inheritance
- Ideally you create new functionality only by
combining existing objects (instance variables in
a class) - Inheritance may play a role. However it is
overused, try for object composition
23What is variable in the design?
- Consider what is variable in your design
- Instead of focusing on what might force a change
to your design - Consider what you might want to change
- Encapsulate the concept that varies
- a theme of many design patterns
- Hopefully there are long term benefits without a
lot of extra work up front
24OO Design Patterns Used
- In the upcoming case study, these design patterns
will help make for a system that is good design - Strategy
- Singleton
- Decorator
- Observer
- We've considered all four
25An Ecommerce System
- There is a TaskController object that handles
sales requests over the internet - When the sales order is requested, the controller
delegates to a SalesOrder object
26Assign Responsibilities
- SalesOrder responsibilities
- Allow users to make an order with a GUI
- Process the order
- Print a sales receipt
27Changing Requirements
- Start charging taxes on order from customers
- need to add rules for taxation, but how?
- modify existing SalesOrder to handle U.S. taxes
- extend the existing SalesOrder object and modify
the tax rules so it applies to the new country - This is an inheritance solution
28Subclassing Solution
TaskController
SalesOrder
SalesTicketPrinter
calcTax()double
US Tax
Rules
Canadian
Tax Rules
CanadianSalesOrder
calcTax()double
29Favor Composition Over Inheritance
- Design pattern theme of composition over
inheritance is ignored in previous design - Here is a different approach
- consider what is variable in the design
- encapsulate the concept the varies
- Accept the fact that tax rules vary country to
country and state to state and county to county,
and city to city and they change quite often
30Alternate Designs
- Another design is to use an abstract class with
an interface (calcTax) and develop a hierarchy - Or we can design an interface to be implemented
by different classes using different algorithms - SalesOrder contain a reference to the correct
object - public interface TaxCalculator
- // Salable objects know price and how taxed
- public double taxAmount(Salable itemSold,
- double quantity)
-
31A Better Design with Strategy
32Why does Strategy make this design better?
- Better Cohesion (hangs together)
- sales tax details are in its own class
- Easy to add tax rules from different countries
- Easier to shift responsibilities
- In the first design (with CanadianSalesOrder
extending USSalesOrder), only TaskController
could determine which type of sales order to use - With Strategy, either TaskController or
SalesOrder could set the TaxCalculator
33Determine What Varies
- What Varies?
- The business rules for taxation
- Current design handles variations at least as
well as the other design design - Current design will handle future variations as
well - A family of tax calculation algorithms have been
encapsulated as objects, they are
interchangeable, this is the Strategy pattern
applied in an Ecommerce system
34Using the Strategy Pattern
- What happens when EnglishTaxer is added
- In England, old-age pensioners are not required
to pay taxes on sales items - How can this be handled?
- 1) Pass age of the Customer to TaxCalculator
object - 2) Be more general and pass a Customer object
- 3) Be even more general and pass a reference to
the SalesOrder object (this) to the TaxCalculator
and let that EnglishStrategy object ask
SalesOrder for customer age (post some html to
the client)
35Is this change bad?
- To handle this new requirement, SalesOrder and
TaxCalculator have to be modified - But the change is small and certainly doable
- Not likely to cause a new problem
- If a Strategy needs more information, pass the
information to the object as an argument - Some objects may ignore the extra parameter
- Strategy can be applied anywhere you hear this
- "At different times, different business rules
apply"
36Singleton Pattern
- Singleton Ensure a class only has one instance
and provide a global point of access to it - The singleton pattern works by having a special
method that is used to instantiate the object - when called, the method checks to see if the
object has already been instantiated - it returns the singleton if instantiated or
constructs a new one if this is the first call to
get the instance - to guarantee this, have a private constructor
37Using Singleton
- TaxCalculators are currently encapsulated as
Strategy objects - How many USTaxer objects are required in this
system? How many CanadianTaxers? - Forces
- The same object is being used over and over again
- More efficient to avoid instantiating them and
throwing them away again and again - Doing all at once could be slow to start up
- Could instantiate these objects as needed
38Only want one when needed
- Dont need more than one instance of each
TaxCalculator class - Solution
- Let Strategy objects handle the instantiation
- Let there be only one instance
- Dont concern clients (SalesOrder) over this
detail - In other words, use the Singleton design pattern
39USTaxer is now a Singleton
- public class USTaxer implements TaxCalculator
-
- private static USTaxer instance // Only one
- private static double taxRate
- private USTaxer()
- taxRate 0.06 // greatly simplified
-
- public static USTaxer getInstance()
- if( instance null )
- instance new USTaxer()
- return instance
-
- public double taxAmount(Salable item, double
quant) - return 0 // TODO Implement tax algorithm
-
40(No Transcript)
41Class constructs the singleton
- Singleton is one of the creational patterns
- TaxCalculator taxer null
-
- for (int j 1 j
- taxer USTaxer.getInstance()
- // There is only one instance of USTaxer
- // The following code would show that tax
someone - // in the US must pay for one Salable item
- System.out.print(taxer.taxAmount(new Salable(),
1)) - Next slide summarizes the system via UML
42dependency
aggregation (Salable is one part of SalesOrder)
composition
implements
43Aggregation vs. Composition
- Definitions from the Unified Modeling Language
Guide - Aggregation A special form of association that
specifies a whole/part relationship between the
aggregate (the whole) and a component (the part) - Composition A form of aggregation with strong
ownership. Once a component is created, its lives
and dies with its whole - A TaxCalculator object is only necessary with a
SalesOrder not used elsewhere
44Other Patterns applied
- In the Ecommerce system, we will now
- Decorate a SalesTicket and
- Observe a Customer
45Decorate SalesTicketPrinter
- Assume the SalesTicketPrinter currently creates
an html sales receipt Airline Ticket - New Requirement Add header with company name,
add footer that is an advertisement, during the
holidays add holiday relevant header(s) and
footer(s), were not sure how many - One solution
- Place control in SalesTicketPrinter
- Then you need flags to control what header(s) get
printed
46One Solution
- This works well if there are few header and
footer options or perhaps just add a few private
helper methods
underline indicates static methods
47Strategy Pattern?
- If there are many types of headers and footers,
with only one being printed each time, use
Strategy - If there are more than one header and footer, and
the ordering changes, and the number of
combinations grows, - use the Decorator design pattern to chain
together the desired functionality in the correct
order needed
48Decorator Again
- Decorator summary repeated Attach additional
Responsibilities to an object dynamically. - Decorators provide a flexible alternative to
subclassing for functionality GoF - Start chain with decorators, end with original
object
Decorator 1
Decorator 2
Concrete Component
Example keyboard new BufferedReader(
new InputStreamReader(
System.in))
49(No Transcript)
50A Simple SalesTicket like Insect
- // Instances of this class are the sales tickets
- // that may be decorated
- public class SalesTicket extends Component
-
- public void printTicket()
- // Hard coded here, but simpler than
- // adding a new Customer class now
- System.out.println("Customer Kim")
- System.out.println("The sales ticket
itself") - System.out.println("Total 123.45")
-
-
51TicketDecorator like AnimalDecorator
- public abstract class TicketDecorator extends
Component -
- private Component myComponent
- public TicketDecorator()
- myComponent null
-
- public TicketDecorator(Component c)
- myComponent c
-
- public void printTicket()
- if(myComponent ! null)
- myComponent.printTicket()
-
52A Header Decorator like Hopping
- public class HeaderDecorator1 extends
TicketDecorator -
- public HeaderDecorator1(Component c)
- super(c)
-
- public void printTicket()
- this.printHeader()
- super.printTicket()
-
- public void printHeader()
-
- System.out.println("_at__at_ Header One _at__at_")
-
53A Footer Decorator like Singing
- public class FooterDecorator1 extends
TicketDecorator -
- public FooterDecorator1(Component c)
- super(c)
-
- public void printTicket()
- super.printTicket()
- this.printFooter()
-
- public void printFooter()
- System.out.println(" FOOTER two ")
-
-
54SalesOrder a client
- public class SalesOrder
-
- public static void main(String args)
-
- SalesOrder s new SalesOrder()
- s.printTicket()
-
- public void printTicket()
- // Get an object decorated dynamically
- Component myST Configuration.getSalesTicket(
) - myST.printTicket()
-
- // calcSalesTax ...
55Simple Configuration
- // This object would determine how to decorate
the - // SalesTicket. This could become a Factory
- public class Configuration
-
- public static Component getSalesTicket()
- // Return a decorated SalesTicket
- return
- new HeaderDecorator1(
- new HeaderDecorator2(
- new FooterDecorator1(
- new FooterDecorator2(
- new SalesTicket() ))))
-
56Output with Current Configuration
- Output
- _at__at_ Header One _at__at_
- Header Two
- Customer Bob
- The sales ticket itself
- Total 123.45
- FOOTER two
- FOOTER two
57SalesOrder delegates to Component to print
ticket
The system on 2 slides
58(No Transcript)
59Observe Customer
- New Requirements Send an email to a new customer
and verify the customer's address with the post
office - If this was it, hard code Customer behavior when
being added to data base
60Or Use Observer
- With additional behaviors (such as send
advertisements via snail mail), there may be a
changing list of objects that need notification
that a new customer is being added - These objects will have different interfaces
- verifyAddress, sendEmail, sendCoupons,
sellPrivateInformationToTelemarketers, .... - Let's change all two, or three, or four objects
into "Observers"
61Observer
- Have Customer extend Observable
- Have all of the objects that need notification
implement Observer (all have the update method) - Have some configurer add the correct observers to
the Customer object with addObservers - Have the addCustomer method send the message
notifyObservers
62Design with Observer