Title: CS1321: Introduction to Programming
1CS1321Introduction to Programming
- Georgia Institute of Technology
- College of Computing
- Module 38
- OO Example Coke Machines
2Ah.the king of caffeinated beverages. Have you
ever thought about how much money is plunked into
vending machines every day to buy these things?
Its a hefty hunk of change. So why dont we
get in on the action? We wish to model a coke
machine in Scheme, using this idea of lexical
closures and object-oriented behavior.
3Coke Machine The State Variables
Real coke machines have varying capacities Real
coke machines hold money. Real coke machines
associate a cost with each coke.
(define cans 0) (define MAX-CANS 0) (define COST
.65) (define cash 0)
Even though max-cans is effectively going to be a
constant, were still going to start it off at
zero. This will allow us to create coke machines
with varying capacities.
4Coke Machine Initialization
We need to be able to specify the maximum number
of cans our coke machine can hold, and initialize
the number of cans we currently hold to that
value
(define (init-machine in-max) (begin (set!
MAX-CANS in-max) (set! cans MAX-CANS)))
5Coke Machine reload
If we run out of cokes in our coke machine, we
need to be able to reload our coke machine.
Lets simplify the problem by only reloading to
our maximum capacity
(define (reload) (set! cans MAX-CANS))
6Coke Machine is-empty?
Now we need a function that returns whether or
not a coke machine is empty.
(define (is-empty?) ( cans 0))
7New Coke Machine vend
Finally, something complex! Logically, we need to
be able to vend a single coke if the machine is
NOT empty. We also need to take in an idea of
cash. If the machine takes in AT LEAST the cost
of a can of coke, and if one is available, we
need to vend a coke, add money to the amount of
cash in the machine, and return the appropriate
change. If the user inserts the incorrect amount
of change, we need to handle that as well
8New Coke Machine vend
(define (vend in-money) (cond (is-empty?)
(display "No cokes left!")) else
(cond (gt in-money COST)
(begin (display "Have a
Coke") (set! cash ( cash
COST)) (set! cans (- cans
1)) (- in-money COST))
else (display
"Add more money"))))
9New Coke Machine how-many
For testing purposes, lets put this function in
(define (how-many) cans)
10Before we go on
Scheme is not exactly the most beautiful language
to emulate this Object Oriented behavior. The
next function were about to see is ugly and
confusing at first. So before we lose ourselves
in those particulars, lets examine what weve
set ourselves up for
11OBJECT
Our goal is to create an object that represents a
coke machine. This object will have values
contained within it and behaviors that act on
those values.
12New Coke Machine service-manager
(define (service-manager service) (cond
((symbol? service 'is-empty?) is-empty?)
((symbol? service 'how-many) how-many)
((symbol? service 'reload) reload)
((symbol? service 'vend) vend) (else
(display "Invalid service"))))
13New Coke Machine service-manager
(define (service-manager service) (cond
((symbol? service 'is-empty?) is-empty?)
((symbol? service 'how-many) how-many)
((symbol? service 'reload) reload)
((symbol? service 'vend) vend) (else
(display "Invalid service"))))
If we think back to the to-do list example, this
service manager does something quite different
than any weve seen thus far. Well examine its
actual behavior in a moment
14make-coke-machine
(define (make-coke-machine max) (local ((define
cans 0) (define MAX-CANS 0)
(define COST .65)
(define cash 0) (define
(init-machine in-max)
(define (reload) ) (define
(is-empty?) ) (define
(how-many) ) (define (vend
in-money) ) (define
(service-manager service) ) )
))
The definitions for these functions are on the
previous slides. Lets look at what the local
actually executes
15make-coke-machine
(define (make-coke-machine max) (local
() (begin (init-machine
max) service-manager)))
We begin by initializing our coke-machine
object. We then return the service manager
(the main functionality) as is typical in
closures.
16Lets figure out how this works
17The functionality that we returned from
make-coke-machine was this
(define (service-manager service) (cond
((symbol? service 'is-empty?) is-empty?)
((symbol? service 'how-many) how-many)
((symbol? service 'reload) reload)
((symbol? service 'vend) vend) (else
(display "Invalid service"))))
As we didnt provide any contracts for our
functions (shame on us!), were going to have to
play around with this function to see what
happens. It looks like this function takes in 4
different types of symbols. Lets try how-many
18(No Transcript)
19(No Transcript)
20(No Transcript)
21(No Transcript)
22(No Transcript)
23Returning Functionality
This service-manager allows us to return
functionality from an object and invoke it on
values rather than invoking the functionality
itself. By this method we can allow ourselves to
have behaviors with varying numbers of
parameters. Lets take another look at to-do
lists service manager...
24(define (service-manager in-service) (cond
(symbol? add in-service) add-in-order
(symbol? retrieve in-service)
retrieve (symbol? remove in-service)
remove (symbol? search in-service)
search-by-name (symbol? print in-service)
print-to-do else (lambda () ERROR)))
Now if we invoke the behavior from our object, we
let the behavior specify how many and what type
of parameters it expects
25Patterns
- So it would seem that we use objects like this
- We create an instance of our object and bind it
to a name. This instance of our object is in
fact the service-manager for our closure. - (define ltobject-namegt (ltobject creatorgt))
- We act on that service manager by passing it the
name of the functionality we want to enact - (ltobject-namegt ltname of functionalitygt)
- This returns to us the actual functionality
itself, which we can then pass parameters to and
use - ((ltobject-namegt ltname of functionalitygt)
ltparametergt)
26Far-fetched?
Well, not terribly. In Java, the language youll
be working with next semester, you can definitely
draw parallels between what we just did and what
you will do CokeMachine CSCokeMachine new
CokeMachine(30) CSCokeMachine.vend(1.00) Syste
m.out.println( CSCokeMachine.howMany())
27Far-fetched?
Well, not terribly. In Java, the language youll
be working with next semester, you can definitely
draw parallels between what we just did and what
you will do CokeMachine CSCokeMachine new
CokeMachine(30) CSCokeMachine.vend(1.00) Syste
m.out.println( CSCokeMachine.howMany())
Here we bind a name to a coke machine object
28Far-fetched?
Well, not terribly. In Java, the language youll
be working with next semester, you can definitely
draw parallels between what we just did and what
you will do CokeMachine CSCokeMachine new
CokeMachine(30) CSCokeMachine.vend(1.00) Syste
m.out.println( CSCokeMachine.howMany())
Here we access functionality and pass a parameter
via ltobject namegt.ltfunctionalitygt(ltparametersgt)
29Far-fetched?
Well, not terribly. In Java, the language youll
be working with next semester, you can definitely
draw parallels between what we just did and what
you will do CokeMachine CSCokeMachine new
CokeMachine(30) CSCokeMachine.vend(1.00) Syste
m.out.println( CSCokeMachine.howMany())
And we do the same here ltobject
namegt.ltfunctionalitygt(ltparametersgt)
30Alternatives?
Is this the best way to model a coke machine?
Certainly not. Were missing a whole mess of
functionality. But lets talk about that later
31Questions?