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
Well done!
You have completed Observer Design Pattern using Java!
You have completed Observer Design Pattern using Java!
Preview
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