Presentation 16 the final one - PowerPoint PPT Presentation

1 / 65
About This Presentation
Title:

Presentation 16 the final one

Description:

Strategy define a family of algorithms, encapsu-late each one, and make them ... during the holidays add holiday relevant header(s) and footer(s), we're not sure ... – PowerPoint PPT presentation

Number of Views:60
Avg rating:3.0/5.0
Slides: 66
Provided by: rickm1
Category:

less

Transcript and Presenter's Notes

Title: Presentation 16 the final one


1
CSC 335 Object-Oriented Programming and Design
Presentation 16 the final one Pattern-Oriented
Design Design Patterns Explained A New
Perspective on Object-Oriented Design Alan
Shalloway, James R. Trott Addison Wesley ISBN
0-201-71594-5
2
Design patterns weve seen
  • Iterator Provide a way to access the elements of
    a collection sequentially without exposing
    underlying representation Iterator,
    ListIterator, Enumeration
  • Strategy define a family of algorithms,
    encapsu-late each one, and make them
    interchangeable diceRerollStrategy, Layout
    Managers
  • Composite Lets clients treat individual objects
    and compositions of object uniformly java.io,
    JPanel

3
Design patterns weve seen
  • Observer Define a 1 to many relationship so when
    one object changes state, all dependents are
    notified and updated automatically. Add
    functionality by attaching other observers
    Windows Explorer
  • Mediator Define an object that encapsulates how a
    set of objects interact while promoting loose
    coupling between those objects Controllers
  • Decorator Attach additional responsibilities to
    an object dynamically. Provides a flexible
    alternative to subclassing java.io streams

4
Design patterns weve seen
  • Factory Define a way to instantiate classes and
    make another class be responsible for
    instantiating classes. The class may use
    arguments or state to determine which is
    appropriate Marty's sound factory,
    NumberFormat.getCurrencyInstance
  • Singleton Ensure a class has only one instance
    and provide a global point of access to it

5
More Design Patterns
  • There are 16 other OO design patterns cataloged
    in the GoF book (weve seen 8 of 23)
  • We'll now consider how to use some of these
    design patterns when designing a system
  • 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

6
Plan 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

7
How 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

8
Principles of Good Design
  • Some guiding principles from GoF
  • Program to an interface, not an implementation
  • Commit to using an interface rather than a
    concrete class
  • Favor object composition over inheritance
  • Ideally you create new functionality only by
    combining existing objects
  • Inheritance may play a role, but it is overused,
    try for object composition
  • Consider what is variable in your design

9
What is variable in the 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

10
OO 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

11
An Ecommerce System
  • There is a controller object that handles sales
    request over the internet
  • When the sales order is requested, the controller
    delegates to a SalesOrder object

12
Assign Responsibilities
  • SalesOrder responsibilities
  • Allow users to make an order with a GUI
  • Process the order
  • Print a sales receipt

13
Changing 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

14
Subclassing Solution
TaskController
SalesOrder
SalesTicketPrinter
calcTax()double
US Tax
Rules
Canadian
Tax Rules
CanadianSalesOrder
calcTax()double
15
Favor 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

16
Alternate Designs
  • Another design is to use an abstract class with
    an interface (calcTax) and develop a hierarchy
  • In Java, we can design an interface and contain a
    reference to an object the implements the
    interface
  • What is the Pattern Name? _____________ ?
  • public interface TaxCalculator
  • // Salable objects know price and how taxed
  • public double taxAmount(Salable itemSold,
  • double quantity)

17
A Better Design with Strategy
18
Why doe Strategy make this design better?
  • Better Cohesion
  • 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
  • In the current design, either TaskController or
    SalesOrder could set the TaxCalculator

19
Determine 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 our Ecommerce system

20
Using 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 the Customer object
  • 3) Be even more general and pass a reference to
    the SalesOrder object (this) to the TaxCalculator
    and let that Strategy object ask SalesOrder for
    customer age

21
Is 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 the Strategy needs more information, pass the
    information to the object as an argument
  • Strategy can be applied anywhere you hear this
  • "At different times, different business rules
    apply"

22
Singleton 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

23
Using 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

24
Only 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
  • Use the Singleton Pattern

25
USTaxer 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.00 // TBA

26
(No Transcript)
27
Class constructs the singleton
  • Singleton is one of the creational patterns
  • TaxCalculator taxer null
  • for (int j 0 j lt 100 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))

28
Other Patterns applied
  • In the Ecommerce system, we will now
  • Decorate a SalesTicket and
  • Observe a Customer
  • Current design of this system is shown on the
    next slide with the CanadianTaxer as a Singleton
  • However, it doesn't have the Customer yet

29
dependency
aggregation (Salable is one part of SalesOrder)
composition
implements
30
Review Aggregation / Composition
  • Definitions from the Unified Modeling Language
    Guide
  • Aggregation A special for 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

31
Decorate 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

32
One Solution
  • This works well if there are few header and
    footer options or perhaps just add a few private
    helper methods to

underline indicates static methods
33
Strategy 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

34
Decorator 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))
35
(No Transcript)
36
A Simple SalesTicket Mammal
  • // 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 Bob")
  • System.out.println("The sales ticket
    itself")
  • System.out.println("Total 123.45")

37
TicketDecorator
  • 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()

38
A Header Decorator
  • 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_")

39
A Footer Decorator like SleepingAnimal
  • 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 ")

40
SalesOrder 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 ...

41
Simple 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() ))))

42
Output with Current Configuration
  • Output
  • _at__at_ Header One _at__at_
  • gtgt Header Two ltlt
  • Customer Bob
  • The sales ticket itself
  • Total 123.45
  • FOOTER two
  • FOOTER two

43
SalesOrder delegates to Component to print
ticket
The other part of the system
44
(No Transcript)
45
Observe 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

46
Or 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,
    sellInformationToTelemarketers, ....
  • Let's change all two, or three, or four objects
    into "Observers"

47
Observer
  • Have Customer extends 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

48
Design with Observer
49
The Decorator Pattern Summary and Another
example
  • Intent
  • Attach additional responsibilities to an object
    dynamically. Decorators provide a flexible
    alternative to subclassing for extending
    flexibility
  • Also Known As
  • Wrapper
  • Motivation
  • Want to add properties such as borders or
    scrollbars to a GUI component or more methods to
    an existing object.
  • Can be done with inheritance, but this limits
    flexibility (couldnt change borders at runtime).
    A better way is to use composition.

50
Applicability
  • Use Decorator
  • To add responsibilities to individual objects
    dynamically without affecting other objects
  • When extending classes is impractical
  • Sometimes a large number of independent
    extensions are possible and would produce an
    explosion of subclasses to support every
    combination
  • this approach is shown next

51
An Application
  • Suppose there is a TextView GUI component and you
    want to add different kinds of borders and/or
    scrollbars to it
  • Currently, there are three types of borders
  • Plain, 3D, Fancy
  • And two scrollbars
  • Horizontal and Vertical
  • An inheritance solution requires15 classes for
    one view

52
Thats a lot of classes!
  • TextView-Plain
  • TextView-Fance
  • TextView-3D
  • TextView-Horizontal
  • TextView-Vertical
  • TextView-Horizontal-Vertical
  • TextView-Plain-Horizontal
  • TextView-Plain-Vertical
  • TextView-Plain-Horizontal-Vertical
  • TextView-3D-Horizontal
  • TextView-3D-Vertical
  • TextView-3D-Horizontal-Vertical
  • TextView-Fancy-Horizontal
  • TextView-Fancy-Vertical
  • TextView-Fancy-Horizontal-Vertical

53
Disadvantages
  • Inheritance solution has an explosion of classes
  • If another type of border were added, how many
    more classes do we need?
  • If another view were added, say ImageView or
    StreamingVideoView, how many more classes do we
    need?
  • Have to instantiate specific classes at
    compiletime
  • would be better to be able to change borders at
    runtime
  • This is inflexible, cant change view or border
    at runtime
  • Use the Decorator Pattern instead (Java does)

54
VisualComponent draw() resize()
Decorator contains a visual component
1
ImageComponent draw() resize()
TextView draw() resize()
Decorator draw() resize()
1
Border draw() resize()
ScrollBar draw() resize()
Fancy draw() resize()
Vert draw() resize()
Plain draw() resize()
3D draw() resize()
Horiz draw() resize()
55
Applicability
  • The TextView class knows nothing about Borders
    and Scrollbars
  • public class TextView
  • public void draw()
  • // Code to draw this Text object
  • public void resize ()
  • // Code to resize this Text object

56
Applicability
  • The ImageView knows nothing about Borders and
    Scrollbars
  • public class ImageView
  • public void draw()
  • // Code to draw this Image Object
  • public void resize ()
  • // Code to resize this Image Object

57
Decorators Contain Components
  • But the decorators need to know about components
  • public class FancyBorder
  • private Component component
  • public FancyBorder(VisualComponent visual)
  • component visual
  • public void draw()
  • component.draw() // forward draw message
    contained obj
  • // Code to draw this FancyBorder object

58
How to use Decorators
  • public class Client
  • public static void main(String args)
  • TextView data new TextView()
  • Component borderData new FancyBorder(data)
  • Component scrolledData new
    VertScrollbar(data)
  • Component borderAndScrolledData
  • new HorzScrollbar(borderData)

59
Motivation Continued
  • The more more flexible containment approach
    encloses the component in another object that
    adds the border
  • The enclosef object is known as the decoree
  • The enclosing object is called the decorator
  • The decorator conforms to the interface of the
    component so its presence is transparent to
    clients
  • The decorator forwards requests to the component
    and may perform additional actions (such as
    drawing a Border) before or after any forwarding

60
Decorator Pattern in Java
  • InputStreamReader
  • ... bridge from byte streams to character
    streams It reads bytes and translates them into
    characters using the specified character
    encoding. JavaTMAPI
  • BufferedReader
  • Read text from a character-input stream,
    buffering characters so as to provide for the
    efficient reading of characters, arrays, and
    lines. JavaTMAPI
  • What programmer's can now code
  • BufferedReader keyboard
  • new BufferedReader(new InputStreamReader(System.i
    n))

61
Example of decorator pattern use
BufferedReader decorates InputStreamReader
BufferedReader readLine() ready()
InputStreamReader read() close()
62
Java streams
  • With gt 60 streams in Java, you can create a wide
    variety of input and output streams
  • this provides flexibility good
  • it also adds complexity bad
  • Flexibility made possible with inheritance and
    classes that accept many different classes that
    extend the parameter
  • You can have an InputStream instance or any
    instance of a class that extends InputStream
  • public InputStreamReader(InputStream in)

63
One Constructor for many subclasses
  • InputStream has these direct known subclasses
  • ByteArrayInputStream, FileInputStream,
    FilterInputStream, InputStream,
    ObjectInputStream, PipedInputStream,
    SequenceInputStream, StringBufferInputStream
  • System.in is an instance of InputStream
  • Check the API
  • We decorated a FileInputStream with an
    ObjectInputStream so you can read objects that
    implement Serializable

64
Write text to a text file wrap a file output
stream (for writing to the disk) with a
PrintWriter--that has println
  • // You must import java.io.
  • PrintWriter outFile null
  • try
  • outFile new PrintWriter (
  • new FileOutputStream(filename) )
  • catch( FileNotFoundException fnfe )
  • outFile.println( "Hello world" )
  • outFile.close() // do NOT forget this!
  • // If you don't close the file, data will be lost!

65
(No Transcript)
Write a Comment
User Comments (0)
About PowerShow.com