Generalizing this Design

Slides:



Advertisements
Similar presentations
When do I need an invariant? CS 5010 Program Design Paradigms “Bootcamp” Lesson 7.4 TexPoint fonts used in EMF. Read the TexPoint manual before you delete.
Advertisements

Real State vs. Simulated State CS 5010 Program Design Paradigms "Bootcamp" Lesson 11.3 © Mitchell Wand, This work is licensed under a Creative.
Basics of Inheritance CS 5010 Program Design Paradigms "Bootcamp" Lesson 12.1 © Mitchell Wand, This work is licensed under a Creative Commons.
Testing Simple Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.6 © Mitchell Wand, This work is licensed under a Creative Commons.
Patterns of Interaction 2: Publish-Subscribe CS 5010 Program Design Paradigms "Bootcamp" Lesson 11.6 © Mitchell Wand, This work is licensed under.
Interfaces CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.2 © Mitchell Wand, This work is licensed under a Creative Commons Attribution-NonCommercial.
Classes, Objects, and Methods CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.1 © Mitchell Wand, This work is licensed under a Creative.
Stateful Objects and Stable Identities CS 5010 Program Design Paradigms "Bootcamp" Lesson 11.2 © Mitchell Wand, This work is licensed under a.
Patterns of Communication Between Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson 11.1 © Mitchell Wand, This work is licensed under.
Converting from Immutable to Mutable Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson 11.4 © Mitchell Wand, This work is licensed under.
Examining Two Pieces of Data CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under a Creative.
The Design Recipe using Classes CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.5 © Mitchell Wand, This work is licensed under a Creative.
Using Inheritance to Share Implementations CS 5010 Program Design Paradigms "Bootcamp" Lesson 12.1 © Mitchell Wand, This work is licensed under.
Introduction to Universe Programs CS 5010 Program Design Paradigms “Bootcamp” Lesson TexPoint fonts used in EMF. Read the TexPoint manual before.
More examples of invariants CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under a Creative.
Model-View-Controller Architecture CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under a Creative.
A Case Study: Space Invaders CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative.
Testing Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative Commons Attribution-NonCommercial.
Patterns of Interaction 2: Publish-Subscribe CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed.
The Design Recipe using Classes CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative.
Callbacks and Interacting Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative.
Testing Mutable Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative Commons.
Generalizing this Design CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative Commons.
Stateful Objects and Stable Identities CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under.
The Last Lecture CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative Commons Attribution-NonCommercial.
Observerables are not Fields CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.7 © Mitchell Wand, This work is licensed under a Creative.
Using Inheritance to Share Implementations CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under.
Functions vs. Classes CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative Commons.
More linear search with invariants CS 5010 Program Design Paradigms “Bootcamp” Lesson TexPoint fonts used in EMF. Read the TexPoint manual before.
Solving Your Problem by Generalization CS 5010 Program Design Paradigms “Bootcamp” Lesson © Mitchell Wand, This work is licensed under.
Converting from Immutable to Mutable Objects CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed.
Classes, Objects, and Interfaces CS 5010 Program Design Paradigms "Bootcamp" Lesson © Mitchell Wand, This work is licensed under a Creative.
CS 5010 Program Design Paradigms “Bootcamp” Lesson 2.4
Model-View-Controller Architecture
The Point of This Course
CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.2
Examining Two Pieces of Data
CS 5010 Program Design Paradigms “Bootcamp” Lesson 5.4
CS 5010 Program Design Paradigms “Bootcamp” Lesson 3.1
CS 5010 Program Design Paradigms "Bootcamp" Lesson 9.4
Introduction to Invariants
CS 5010 Program Design Paradigms “Bootcamp” Lesson 8.7
Halting Functions for Tree-Like Structures
CS 5010 Program Design Paradigms "Bootcamp" Lesson 12.1
From Templates to Folds
Callbacks and Interacting Objects
CS 5010 Program Design Paradigms “Bootcamp” Lesson 3.4
CS 5010 Program Design Paradigms “Bootcamp” Lesson 3.2
CS 5010 Program Design Paradigms "Bootcamp" Lesson 9.3
Patterns of Interaction 2: Publish-Subscribe
Patterns of Interaction 2: Publish-Subscribe
CS 5010 Program Design Paradigms “Bootcamp” Lesson 7.5
Solving Your Problem by Generalization
A Case Study: Space Invaders
Testing Mutable Objects
CS 5010 Program Design Paradigms “Bootcamp” Lesson 6.5
The Design Recipe using Classes
More examples of invariants
ormap, andmap, and filter
The Iterative Design Recipe
CS 5010 Program Design Paradigms "Bootcamp" Lesson 12.1
Rewriting your function using map and foldr
Introduction to Universe Programs
Examining Two Pieces of Data
A Case Study: Space Invaders
When do I need an invariant?
CS 5010 Program Design Paradigms “Bootcamp” Lesson 8.3
CS 5010 Program Design Paradigms “Bootcamp” Lesson 3.4
Design Strategies 3: Divide into cases
Presentation transcript:

Generalizing this Design CS 5010 Program Design Paradigms "Bootcamp" Lesson 10.5 © Mitchell Wand, 2012-2016 This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

Problems with our design so far It used to be that World% created new widgets by trapping keystrokes in its after-key-event method. But what if we want to add new objects by some other means (e.g. pushing a button on the screen)? And having widget creation handled by the World means the World has to know both about distributing messages AND about keystrokes that's a violation of one task per function.

Solving this problem We'll do this in three steps: We'll make the world stateful, too We'll give it methods for adding widgets and stateful widgets. Then we'll create a ball factory to create balls and add them to the world. the factory will know about the wall, so the balls it creates will be equipped with knowledge about the wall.

SWorld<%> ;; The World implements the SWorld<%> interface (define SWorld<%> (interface () ; -> Void ; GIVEN: no arguments ; EFFECT: updates this world to its state after a tick after-tick ; Integer Integer MouseEvent-> Void ; GIVEN: a location ; EFFECT: updates this world to the state it should be in ; following the given mouse event at the given location. after-mouse-event ; KeyEvent : KeyEvent -> Void ; GIVEN: a key event ; following the given key event after-key-event ; -> Scene ; GIVEN: a scene ; RETURNS: a scene that depicts this World to-scene )) This is just like what we did before: We change the contracts to return Void, and replace RETURNS with EFFECT in the purpose statements.

SWorld% ; ListOfWidget ListOfSWidget -> World (define (make-world objs sobjs) (new SWorld% [objs objs][sobjs sobjs])) (define SWorld% (class* object% (SWorld<%>) (init-field objs) ; ListOfWidget (init-field sobjs) ; ListOfSWidget (super-new) ;; after-tick : -> Void ;; Use map on the Widgets in this World; use for-each on the ;; stateful widgets (define/public (after-tick) (begin (for-each (lambda (obj) (send obj after-tick)) sobjs) (set! objs (map objs)))) We replace each call to make-sworld or new with a suitable set!, just as in the preceding lesson.

We need to modify our call to big-bang ; run : PosReal -> World ; GIVEN: a frame rate, in secs/tick ; EFFECT: runs an initial world at the given frame rate ; RETURNS: the world in its final state (define (run rate) (big-bang (initial-world) (on-tick (lambda (w) (begin (send w after-tick) w)) rate) (on-draw (lambda (w) (send w to-scene))) (on-key (lambda (w kev) (begin (send w after-key-event kev) w))) (on-mouse (lambda (w mx my mev) (send w after-mouse-event mx my mev) w))))) The methods of the world used to return a new world, but not any more. big-bang still expects its handlers to return a world, so we do this explicitly by writing (begin (send w ...) w) . The world is stable; it just changes its internal state. So w is the right world to return to big-bang.

We still initialize the world in the same way ;; initial-world : -> SWorld ;; RETURNS: a world with a wall and a ball that knows about ;; the wall. (define (initial-world) (local ((define the-wall (new Wall%)) (define the-ball (new Ball% [w the-wall]))) (make-sworld (list the-ball) (list the-wall))))

Now let's add methods to add new widgets to the world First we add it to the interface SWorld<%> : ; Widget -> Void ; GIVEN: A widget ; EFFECT: adds the given widget to the world add-widget ; SWidget -> Void ; GIVEN: A stateful widget add-stateful-widget

And the method definitions: (define/public (add-widget w) (set! objs (cons w objs))) (define/public (add-stateful-widget sw) (set! sobjs (cons sw sobjs)))

Now we can build a ball factory (define BallFactory% (class* object% (SWidget<%>) (init-field world) ; the world to which the factory adds balls (init-field wall) ; the wall that the new balls should bounce ; off of. (super-new) (define/public (after-key-event kev) (cond [(key=? kev "b") (send world add-widget (new Ball% [w wall]))])) ;; the Ball Factory has no other behavior. Return nonsense values for Void, to aid in debugging. (define/public (after-tick) 15) (define/public (after-button-down mx my) 16) (define/public (after-button-up mx my) 17) (define/public (after-drag mx my) 18) (define/public (add-to-scene s) s) )) The factory receives key events from the world. On each "b", it creates a new ball, and then passes the new ball to the world as an argument to add-widget.

And let's initialize the system ;; initial-world : -> World ;; RETURNS: a world with a wall, a ball, and a factory (define (initial-world) (local ((define the-wall (new Wall%)) (define the-ball (new Ball% [w the-wall])) (define the-world (make-world (list the-ball) (list the-wall))) (define the-factory (new BallFactory% [wall the-wall][world the-world]))) (begin (send the-world add-stateful-widget the-factory) the-world))) Create a wall Create a ball that knows about the ball Create a world with the ball and the wall Create a factory that knows about the wall and the world Add the factory to the world Return the resulting world

We just created a cyclic structure! Notice: the factory needed to know about the world, and the world needed to know about the factory. This is a cyclic structure. You can't build a cyclic structure without state.

Wasn't that fun? Go play with 10-5-ball-factory.rkt Draw a diagram of the various classes in this system. Draw a diagram of the different objects in this system.

Key Points for Lesson 10.5 We applied the iterative design strategy in an object-oriented system At every step, we first designed the interface, so we'd know what our methods were supposed to do. Then we designed the methods. We needed a cyclic structure, so both the world and the factory needed to be stateful.

Next Steps Study 10-5-ball-factory.rkt in the Examples folder. If you have questions about this lesson, ask them on the Discussion Board Go on to the next lesson.