Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's finish up our simulation improvements by adding a new tool that observes tables, the restaurant pager!
Additional possible pitfalls
- Careful of the state being stale see the Specific Implementation Problems section.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
How did you do?
0:00
This is how I solved the problem.
0:01
So, if we look in the main loop here,
we're gonna kill this bus table, right?
0:02
So I'm just gonna copy this part of it and
I'm gonna get rid of the rest of this.
0:07
This whole switch here,
let's get rid of that.
0:11
And I'm gonna flip over to the assistant.
0:14
And in here, it's complaining so
implement the methods.
0:18
And I'm gonna pull out right away.
0:23
I'm gonna pull out that table.
0:25
Just like before,
we'll do that downcast to a table.
0:30
And we know that if
the status of the table,
0:34
if the status needs busing,
we're gonna bus that table.
0:39
There we go.
0:49
Now, one thing to note is I'm not
using the arg that was passed in,
0:51
even though it is status.
0:54
When update methods on observers
cause other observers to be notified,
0:55
you end up in this weird nested state.
0:59
And it can happen if
things get out of sync.
1:01
So be cautious of using
that value as it could be
1:03
a stale representation
of the actual truth.
1:06
Now that's why I'm always using the table.
1:09
We'll explore that here in a little bit.
1:11
Check the teacher's notes for more.
1:13
Okay, so now let's go make sure that
those assistants are watching the tables
1:15
alongside the others.
1:19
So, in here, we can go ahead and
we've got Charlie, so
1:21
let's pair up Charlie with Alice here.
1:26
So let's say, Charlie, Charlie, Charlie.
1:29
And then for Bob, we'll have Bob and
Darla work together.
1:36
That should make things
a little bit more even as well,
1:42
like we were seeing, Charlie was
getting all the other work before.
1:45
Okay, so this loop is now nothing but
silliness, right?
1:50
So let's go ahead, let's remove that.
1:54
So what we wanna do is,
1:57
right before we start now is we
wanna kick off all those observers.
1:59
And one way to do that is
by just setting the state.
2:03
And at the start of the day,
the tables are gonna be available, right?
2:06
So we can just say, table.setStatus, and
2:09
we'll set it to status available,
there we go.
2:12
So we'll loop through each one of them,
set it to available and
2:16
then we want time to pass.
2:19
We still want to give them enough time,
so let's just past 30 seconds.
2:20
And since everything else is gonna
be running in it's own thread,
2:23
that should be enough to get
all the observers to work.
2:26
So, you know what though,
2:29
we should make sure that we remove the
observers when the shift is over, right?
2:31
You can remove observers one by one,
2:35
by passing in the specific observer
that you'd like to remove.
2:37
Or you can just remove them all, so
I think that sounds like the right answer.
2:40
So each one of our tables has an observer.
2:44
So we'll say, tables for each,
forEach and hold path, we get a table.
2:47
And we'll say, table.deleteObservers,
because there could be multiple observers.
2:54
In fact, there are,
they got the dashboard.
2:57
After I delete observers, and
2:59
the dashboard now we have all
the employees are watching the table, so.
3:02
Wow, that's looking good.
3:09
Now everything is rewritten and
we close out almost all the issues.
3:10
We should probably try a test run
before we get ahead of ourselves.
3:14
So let's go back up here and
we'll choose run simulator.main.
3:16
Nice.
3:21
So it's going, the dashboard
refreshing all the time by itself.
3:23
Quite a lot of refreshes, but that's okay.
3:28
No one's having to do that.
3:31
Alice is saying,
here's your menus for five.
3:33
Look like the tables, just by the fact
of getting that switch taken out,
3:35
looks like the tables are getting
finished and occupied, and
3:39
the bills are getting paid more.
3:42
So the availability problem
is taken care of for sure.
3:43
Looks like that was a really nice
way to get things to work, right?
3:48
So, let's go and
let's close out this ticket.
3:53
Probably see the favor
availability of the guests.
3:57
And we have the show pager opportunity,
4:00
this is what the pager was
that I was talking about.
4:02
Before we get there though,
let's talk about it.
4:05
The things in this script
are only loosely coupled, right?
4:06
We can change the implementation of what
happens in this code in the main here,
4:12
this wouldn't change much, right?
4:16
Like this is probably
just normal set up here.
4:17
And probably that would be done
dynamically like this is kind of the whole
4:20
body of everything.
4:23
That's pretty cool, right?
4:25
The table isn't in the know about what is
happening anymore and that's great, right?
4:27
It doesn't need to be.
4:31
Okay.
So let's get back to that pager.
4:33
So remember this pager just kind of
just buzzes when the tables are ready.
4:35
And it's gonna be a brand
new type of observer.
4:39
So, we should be able to knock
that out pretty quick, right?
4:41
The pager can observe the table and
when it's available, we'll make it buzz.
4:44
Seems pretty straight forward
in the style, doesn't it?
4:50
So let's see, that's the tool.
4:53
So let's just add a new tool.
4:56
Let's go in our project here,
in our project and if we scroll over
4:58
here to tools, make a new Java class and
we'll call it, Pager.
5:03
And I wanna go ahead and
get full screen on this.
5:11
Let's go ahead and
have it implement the observer.
5:17
Right away implement that missing method.
5:25
So in this case, now, I just wanna
show off what it might look like.
5:30
Why don't we use the arg parameter here.
5:34
So remember the arg was the status
that was pushed in, and
5:36
so what do we say, we said?
5:39
So it's a status, and
we'll pull in status, and
5:42
we'll make this be a status, and
again we're down casting, right?
5:45
Cuz they're objects.
5:50
And that's the right status.
5:52
And we wanted to say, if the status
is equal to Status.AVAILABLE,
5:55
that's when we want it to buzz, right?
6:01
So here we'll just print out really quick,
6:05
BUZZZZZ, and we'll say table,
number is ready,
6:10
given you Y, you know what?
6:16
I mean, first of all,
we need to make this a printf, so
6:21
that we can pass in a format string and
we need to get a hold of the table anyway.
6:24
So, we'll do that.
6:29
Pull the table out from
this observable here.
6:32
And we'll say table.getPosition, no,
don't want to get number of seats.
6:44
I wanna do getPosition number.
6:50
I want that to happen so that,
6:51
just we know it's clear when the buzzer
is buzzing, here is what it's gonna do.
6:53
So, in this situation, a pager really
shouldn't exist without a table, right?
6:57
So, why don't we make
a constructor that accepts,
7:04
only way to create one of these
is by passing the table, right?
7:08
It will always be assigned to a table, but
I am gonna hijack our pager example here,
7:13
just to show you a little something
that you should be aware of.
7:17
Since we're not gonna keep
a reference at all to this table.
7:20
What we'll do,
is add an observer to ourselves, right?
7:23
So, the tables passed in and
the table is an observable.
7:26
So, we're gonna say table.addObserver,
and we're gonna say this.
7:30
So back on our simulator here.
7:35
Now, when we are looping through
these tables, let's go ahead and
7:37
let's make a pager for each of them,
and then the hostess can have this.
7:41
So let's say for each table.
7:46
And now here's what we're gonna do.
7:48
Is we're gonna make this a brand new
pager inside of a loop here, right?
7:50
So we're not going to have a reference
at all when the page was created.
7:54
It's just gonna get created.
7:59
Now, because in the constructor we
observe the table, it's gonna live on.
8:00
Now, the reason for
8:05
that is because the table holds an object
reference in its observers list.
8:06
What that means is,
it will never get garbage collected.
8:10
And the only way that we can get rid
of it is by using that deleteObservers
8:13
method, right?
8:18
The only way to get rid of that pager
is we're going to have to delete
8:18
all observers.
8:21
Now, this could potentially cause
a memory leak, as you can imagine,
8:22
there could be a lot of
observers that we never remove.
8:25
Don't forget to remove them.
8:28
All right, ready?
8:30
Let's do this,
let's see how our pages are doing.
8:31
Let's take a look up here, there is
some serious buzzing happening around,
8:35
the being one, two, three,
four, [SOUND] awesome.
8:39
And they're finding the patrons and
when the patrons are ready, and
8:41
they've been back,
the thing should buzz again.
8:45
So there's should be a buzz in here,
someplace.
8:48
There's another buzz, there we go,
buzz number table four is ready.
8:53
So, guess what?
8:57
Our client is so excited,
loves it and he wants even more,
8:59
he wants to buy more stuff from us.
9:02
This is amazing.
9:04
So it's a good thing that we can
easily add and remove tools, right?
9:05
What are your opinions on the out of
the box Java util observable observer
9:09
solution?
9:14
Then make sure to share your
thoughts with the community.
9:14
So the loudest complaint
about the observable class
9:17
is that it is in fact a class.
9:19
Now, that's fairly unusual in the JTK, and
9:22
due to the single inheritance
nature of this language.
9:25
It makes the implementation
somewhat tricky.
9:27
It also limits the ability
to make your own,
9:30
since there's no interface
to find just the class.
9:32
And several of the methods
actually have protected access, so
9:35
you couldn't even
override them if you try.
9:38
Secondly, the method that is required to
be added by implementors of the observer
9:41
interface.
9:45
Which happens to be the unfortunately
ambiguously named update,
9:45
takes two parameters that are objects.
9:50
So that means there's always
downcasting happening.
9:53
Now remember, this original code was
written before generics were available.
9:55
So, these two big complaints lead to
a lot of people writing their own
9:59
implementations.
10:03
And when you have a fairly controlled
set of objects attempting to perform
10:04
this pattern.
10:08
Well, sometimes, it does just make
more sense to craft your own.
10:08
In fact, why don't we do that
right after this quick break.
10:12
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up