Type Laundering - PowerPoint PPT Presentation

About This Presentation
Title:

Type Laundering

Description:

Cloning, continued... So, finally, the cloning machine will be able to receive an animal ( an instance ... { return template.clone ... – PowerPoint PPT presentation

Number of Views:19
Avg rating:3.0/5.0
Slides: 44
Provided by: cseW
Category:

less

Transcript and Presenter's Notes

Title: Type Laundering


1
Type LaunderingPrototype Pattern
  • Kunal Chaudhary

2
Prototype Pattern
  • Dr W. W.

3
Applicability
  • When the classes to instantiate are specified at
    run-time, for example, by dynamic loading or
  • To avoid building a class hierarchy of factories
    that parallels the class hierarchy of products
    or
  • It may be more convenient to install a
    corresponding number of prototypes and clone them
    rather than instantiating the class manually.

4
Participants
  • Prototype (Graphic)
  • declares an interface for cloning itself.
  • ConcretePrototype(Staff, WholeNote, HalfNote)
  • implements an operation for cloning itself.
  • Client (GraphicTool)
  • creates a new object by asking a prototype to
    clone itself.

5
UML Diagram
6
Consequences
  • Adding and removing products at run-time.
  • Specifying new objects by varying values.
  • Specifying new objects by varying structure.
  • Reduced subclassing.
  • Configuring an application with classes
    dynamically.

7
Implementation Issues
  • Using a prototype manager.
  • Implementing the Clone operation.
  • Initializing clones.

8
Dr W. W.s Story
  • It is a painful road to achieve the success in
    Dr. W. Ws Diabolical plan to conquer the world.
  • But he did it using the Prototype Pattern.

9
Multiple Frankesteins from a Prototype
  • So, the cloning machine looks like this
  • class CloningMachine
  • function CloningMachine( )
  • public function buildClone( ) frankenstein
  • return new frankenstein( )
  • public function buildManyClones( cloneNum
    Number )
  • var returnArray Array new Array( )
  • for( var k0 klt clonesNum k )
  • returnArray k new frankenstein( ) return
    returnArray

10
Code!
  • And the frankenstein will be like
  • class frankenstein function frankenstein( )
  • trace( "beeeee. I'm a new frankenstein" )

11
(No Transcript)
12
Smart plan again (still lacks..)
  • So, he decides to add the functionality needed to
    clone horses. How?. Look
  • class CloningMachine
  • function CloningMachine( )
  • public function buildClone( )
  • frankenstein
  • return new frankenstein( )
  • public function buildhorseClone( )
  • horse return new horse( )
  • public function buildManyClones( cloneNum
    Number )
  • var returnArray Array new Array( )
  • for( var k0 klt clonesNum k )
  • returnArray k new frankenstein( ) return
    returnArray

13
AAAAGGHHHHH!!!!!
14
A new idea, but not enough
  • After thinking about the problem carefully,
    Professor W.W. gives it another try
  • class CloningMachine
  • function CloningMachine( )
  • public function buildClone( type String )
  • Object
  • if( type "frankenstein" )
  • return new frankenstein( )
  • else if ( type "horse" )
  • return new horse( )
  • public function buildManyClones( cloneNum Number
    )
  • var returnArray Array new Array( )
  • for( var k0 klt clonesNum k )
  • returnArray k new frankenstein( )
  • return returnArray

15
Look Below
  • So, heres a frankenstein
  • class frankenstein implements ICloneable
    function frankenstein( )
  • trace( "Hi, I will be cloned soon" )
  • public function clone( ) ICloneable
  • trace( "Beeee, I'm a new frankenstein" )
  • return new frankenstein( )
  • public function toString( ) String
  • return " Hi, I'm a frankenstein. "

16
Horse Implementation
  • And heres a horse
  • class horse implements ICloneable
  • function horse( initFlag Boolean )
  • trace( "Muuuu, I'm a horse. I will also be
    cloned soon" )
  • if( initFlag true )
  • init( )
  • private function init( )
  • trace( "I'm an initialized horse, whatever that
    means" )
  • public function clone( ) ICloneable
  • return new horse( true )
  • public function toString( ) String
  • return " Yes, I'm a cloned horse, muuuuuu "

17
New Cloning Machine
  • And Professor W.W. will want to do something
    like this
  • var cMachine CloningMachine new
    CloningMachine( )
  • cMachine.buildClone( new frankenstein( ) )
  • cMachine.buildClone( new horse( ) )
  • trace( "--" )
  • var frankensteinClones Array
    cMachine.buildManyClones( 5, new frankenstein( )
    )
  • var horseClones Array cMachine.buildManyClones(
    5, new horse( ) ) trace( "--" )
  • trace( "frankensteinClones "
    frankensteinClones )
  • trace( "horseClones " horseClones )

18
Cloning, continued
  • So, finally, the cloning machine will be able to
    receive an animal ( an instance of a class ), and
    tell it to create as many copies of itself as
    needed
  • class CloningMachine
  • function CloningMachine( )
  • public function buildClone( template
    ICloneable ) ICloneable
  • return template.clone( )
  • public function buildManyClones( clonesNum
    Number, template ICloneable ) Array
  • var returnArray Array new Array( )
  • for( var k0 klt clonesNum k )
  • returnArray k template.clone( )
  • return returnArray

19
Bad News !!!
  • Dr. W. W. lost and still didnt win over the
    world because apparently GOODNESS WINS OVER
    PROTOTYPE PATTERN!!!!!

20
Good uses of Prototype pattern
  • The first widely known application of the pattern
    in an object-oriented language was in ThingLab,
    where users could form a composite object and
    then promote it to a prototype by installing it
    in a library of reusable objects.

21
Related Patterns
  • Prototype and Abstract Factory are competing
    patterns in some ways.They can also be used
    together, however. An Abstract Factory might
    store a set of prototypes from which to clone and
    return products objects.
  • Designs that make heavy use of the Composite and
    Decorator patterns often can benefit from
    Prototype as well.

22
Type Laundering
  • If you are using the dynamic cast again and again
    because your framework does not let you make the
    extensions to its interfaces then my friend you
    have bugs in your design.

23
Good News!
  • You can turn those bugs into useful features.
  • Thanks to type laundering!

24
Example
  • Take the vending machine. Its CoinInsertedEvent
    subclass adds a Cents getCoin() operation that
    returns the value of the coin a customer
    deposited. Another kind of event,
    CoinReleaseEvent, gets instantiated when the
    customer wants his or her money back. These
    operations and others would be implemented using
    rep. Clients of these events could of course use
    rep directly, assuming it's public.
  • But there's little reason to make it so rep
    offers almost no abstraction, and it makes
    clients work pretty hard to get at the
    information they need. More likely, rep would be
    protected---of interest only to subclasses, which
    use it to implement more specialized interfaces.

25
Dealing with Loss
  • Since there is no universal interface for events,
    all that the framework knows about events is that
    they implement a basic interface because events
    are defined long after the framework is designed.
  • There are 2 questions that arise
  • How does the framework create instances of
    domain-specific subclasses?
  • How does application code access
    subclass-specific operations when all it gets
    from the framework is objects of type Event?

26
1st Answer
  • Answer to the 1st question lies in defining one
    of the many creational patterns within the
    framework.
  • Example By defining factory method pattern in
    the framework, a new instance of domain-specific
    Event subclass can be obtained.

27
2nd Answer
  • Answer to the 2nd question lies in another
    question, which is, are there patterns for
    recovering type information from an instance?
  • Using visitor pattern lost type information can
    be recovered without resorting to dynamic casts
    to do the same.

28
Celebrate Adversity
  • The whole point is to use the loss of type
    information to our advantage and not mourn about
    it.
  • Lets leave event for now and lets move on the
    issues in the memento pattern.

29
What is Memento?(Small review)
  • Memento captures and externalizes an objects
    state in order to restore the object to the same
    state at a later time.
  • Externalization must not violate encapsulation.

30
Cursor Example
  • Here is an example
  • Structure s
  • Cursor c
  • for (s.first(c) s.more(c) s.next(c))
  • Element e s.element(c)
  • // use Element e
  • The cursor has no client-accessible operations.
  • The way to the pull this off is to give the
    object two different interfaces in C.

31
A Need in Friend
  • Using the friend keyword allows access to a broad
    interface while limiting access to other classes.
  • class Cursor
  • public
  • virtual Cursor()
  • private
  • friend class Structure
  • Cursor () _current 0
  • ListElem current ()
  • return _current // gets _current void current
    (ListElem e) _current e // sets _current
  • private
  • ListElem _current

32
Better Code
  • In this case, structure operations manipulate
    _current to keep track of the point in the
    traversal .
  • class Structure
  • // ...
  • virtual void first (Cursor c)
  • c.current(_head) // _head is the head of the
    linked list, // which Structure keeps internally
  • virtual bool more (Cursor c)
  • return c.current()-gt_next ! 0
  • virtual void next (Cursor c)
  • c.current(c.current()-gt_next) // set current to
    next ListElem
  • virtual Element element (Cursor c)
  • return c.current()-gt_element // ...

33
Problems in Memento
  • The memento pattern furrows away only that much
    information in cursor memento which is necessary
    to mark the current stage of traversal.
  • A shortcoming is that substructure code cannot
    access cursors covert interface.
  • It cannot implement other cursor dependent
    functionality because it cannot override the
    cursor-handling operations inherited from
    structure.

34
Alternate way
  • One work around is to define protected operations
    in structure.
  • class Structure
  • // ...
  • protected
  • ListElem current (Cursor c)
  • return c.current()
  • void current (Cursor c, ListElem e)
    c.current(e) // ...
  • It extends structures privileges to its
    subclasses.

35
Events loss is Cursors Gain
  • The way we transform a design bug into a feature
    is known as type laundering and this is how it is
    done
  • The idea is to define an abstract base class for
    Cursor that includes only those aspects of its
    interface that should be public.
  • class Cursor
  • public virtual Cursor ()
  • protected
  • Cursor ()

36
progress in the Cursor Example
  • Just so that the cursor acts as an abstract
    class, the constructor is protected to preclude
    instantiation.
  • class ListCursor
  • public Cursor
  • public
  • ListCursor ()
  • _current 0
  • ListElem current ()
  • return _current
  • void current (ListElem e)
  • _current e
  • private
  • ListElem _current

37
Better Arrangement
  • This arrangement means that Structure operations
    that take a Cursor as an argument must downcast
    it to a ListCursor before they can access the
    extended interface
  • class Structure
  • // ...
  • virtual void first (Cursor c)
  • ListCursor lc
  • if (lc dynamic_castltListCursorgt(c))
  • lc-gtcurrent(_head)
  • // _head is the head of the linked list, //
    which Structure keeps internally // ...

38
Instantiation
  • The final task to this design is to determine how
    cursors get instantiated.
  • We use a variation on Factory Method to abstract
    the instantiation process.
  • class Structure
  • public // ...
  • virtual Cursor cursor ()
  • return new ListCursor
  • // ...

39
Another problem
  • But, since something of type Cursor is returned
    by cursor( ), clients can access
    subclass-specific operation only when they start
    dynamic casting in order to find out the type.
  • Meanwhile, structure subclasses are free to
    redefine cursor-manipulating operations.

40
Memento Comparison
  • The following diagram illustrates type-laundering
    based implementation and how it differs from
    implementation based in memento pattern.

41
Diagram
42
Main differences
  • The most important difference is the use of
    ConcreteMemento subclass that adds the privileged
    interface to the bare-bones Memento interface.
  • Type laundering absolves a C implementation
    from using friend and having to work around its
    shortcomings.

43
Conclusion
  • Basically, Type laundering cleans up your design
    and makes it efficient with a lot less work.
Write a Comment
User Comments (0)
About PowerShow.com