Bummer! This is just a preview. You need to be signed in with a Pro account to view the entire video.
Start a free Basic trial
to watch this video
In order to get that "I need the observer feeling", let's take a look at a quasi-complex multi-threaded code base, and try to make some changes to it.
Learn more
- Java SE tutorial - Reduction for more information on groupingBy and the concepts behind it.
- Java SE tutorial - Concurrency and specifically Executors
- Java SE tutorial - Abstract Methods and Classes
-
0:00
Okay, before we start on our journey,
-
0:02
I want to remind you of an important piece of advice.
-
0:05
When you're developing you should not start out with a pattern in mind.
-
0:09
Only use patterns when you actually need them.
-
0:11
Now again, this is because using a pattern can cause a lot of overhead, but
-
0:16
when you need it, you'll feel it.
-
0:18
Now, I realize that understanding that feeling when you aren't even sure what it
-
0:22
feels like is probably pretty hard to imagine.
-
0:24
So what I've done is to build up a rather complex multi-threaded application,
-
0:29
to try and help you have that, I need the observer pattern, feeling.
-
0:34
So, here's the scenario.
-
0:35
Let's imagine that we,
-
0:36
you and I, we work for a company that helps provide consultation to restaurants.
-
0:41
We specialize in efficiency.
-
0:44
We suggest different tools and products to make the restaurant's customers flow
-
0:47
in and out in the best possible way.
-
0:49
We've developed some software that helps us demo to our clients,
-
0:53
through simulation, how much better their restaurant could run.
-
0:56
And we've created some simulation software that we use to pitch our ideas.
-
1:01
Running a restaurant efficiently is a difficult problem space.
-
1:04
The better your restaurant performs, the harder it gets to run effectively.
-
1:08
Getting patrons sat down, waited on, fed, and
-
1:10
then cleaning up their tables, becomes a very critical part of your business.
-
1:14
Our first client of the day is having problems with communication between their
-
1:17
staff members.
-
1:18
You know, the tables been cleaned and it's ready.
-
1:20
But the waiter or waitress isn't told about it and patrons are left waiting.
-
1:24
So they're contemplating installing a tablet based dashboard that
-
1:27
we suggested for them.
-
1:28
The dashboard helps keep track of the different tables and
-
1:30
what state they're in.
-
1:31
All the employees, the wait staff and the assistance,
-
1:34
they can look at their dashboard and decide what their next action should be.
-
1:38
Let's take a look at the current implementation.
-
1:40
Okay, so if we open up the restaurant module here.
-
1:44
We'll open that up and then we'll open up src, main, java.
-
1:49
And if we open up down here to the Simulator,
-
1:52
I can show you how this is kicking off.
-
1:55
So this is just the main method here, this simulator and it's got a static void main.
-
2:01
And what I want to show off first is we can create these new tables here,
-
2:06
so there's a table model, so if we open that up and take a look.
-
2:10
We can see that it takes a position number,
-
2:12
which is sort of like a primary key for each one of the tables.
-
2:16
Tables are usually numbered in restaurants and there's also a number of seats,
-
2:20
how many people can sit there.
-
2:23
It also it has a status, let's take a look at what those statuses are.
-
2:27
So, looks like the status is occupied.
-
2:32
So that means that there's people sitting there, they're finished,
-
2:35
they're done eating, they're closing out their bill.
-
2:37
So the server is gonna run the bill.
-
2:40
Needs bussing, that lets the assistant know that the table should be cleaned.
-
2:44
Bussing is the actual act of cleaning it and
-
2:46
then finally we have available when the table's ready.
-
2:49
So if we pop back here to our simulator, let's look,
-
2:54
next up we have a dashboard and that's what we're trying to sell here, right?
-
2:59
So, now let's open that up.
-
3:01
It's pretty basic.
-
3:03
And it shows the whole status of the restaurant in one view.
-
3:07
So what happens is you can call this add table method and
-
3:10
then there's this render method.
-
3:12
And in here, basically we loop through each of the tables that are available and
-
3:17
we group them.
-
3:18
And this is kind of making use of streams and
-
3:22
some Java 8 collector bits that we used to produce a nice looking little report.
-
3:27
It's actually a pretty great use of grouping to create a map
-
3:30
based on the status of the table.
-
3:32
Check the teacher's note for more on this.
-
3:34
So basically, and then it just loops through each one of those states, right?
-
3:37
So each one of status is a loop through and it prints out a pretty little report.
-
3:41
All right. So back to our simulation,
-
3:43
we'll see then that the tables loop through each one of them and
-
3:46
for each of those we call this method reference, add table.
-
3:49
So the dashboard will now have all of the tables that are there.
-
3:54
Okay and then we start building out our servers, so
-
3:56
we have, these are the waiters and the waitresses.
-
3:58
So let's take a look really quick at how we're building these.
-
4:01
So we have an Alice and a Bob server, so let's go ahead and
-
4:04
look at what the server definition is here.
-
4:06
So the server has a couple of public methods,
-
4:09
they can do a lead the table, right?
-
4:12
So when you first meet the people and bring to the table and
-
4:15
then also there's a close out table.
-
4:17
Now one thing that's a little tricky, is that we don't want the task
-
4:21
that the server's performing to block other workers, right?
-
4:25
Now, that's not how things work in real life, right?
-
4:28
Things run at the same time, they run concurrently.
-
4:31
So, definitely the first server can be waiting on a table and
-
4:34
that shouldn't block the other server, right?
-
4:36
You can have a lot of waiters and waitresses in a restaurant.
-
4:39
So this is of course a thing that you can do in code,
-
4:42
cuz obviously you'd need to, right?
-
4:44
It's called concurrency and it's usually done by using threads.
-
4:49
I've employed concurrency here, just a bit,
-
4:52
using an approach called executers and I tried to abstract away
-
4:56
the concept by having performed task take a runnable or a lambda.
-
5:00
So right, there's this perform task here and it takes a runnable.
-
5:04
So you pass it in a lambda and it will do that and
-
5:07
when perform task is happening, the server will be marked as unavailable.
-
5:12
But it won't block other employees right?
-
5:14
So typically what we do is we put in some code to make the thread sleep, so we can
-
5:19
kind of simulate how long something takes so that's what this pass time is here.
-
5:23
Speaking of which.
-
5:25
Server extends an abstract class called Employee,
-
5:29
which provides some common functionality.
-
5:31
Like perform task, for instance.
-
5:33
So perform task is in here, right?
-
5:34
So it's going to say, isAvailable, run the task.
-
5:37
Now they're available.
-
5:39
We also have a static utilities class.
-
5:42
If we open that up, Utilities.
-
5:44
That has this pastTime method and you just pass at the number of seconds and
-
5:48
we'll go ahead and take care of sleeping there.
-
5:50
Thats what thats called, sleeping, as we make times pass.
-
5:52
So, let's pop back over to Employee real quick and
-
5:55
I wanna to show off that there is a method called, announce.
-
6:00
And you basically pass in a message template and
-
6:02
the rest of it gets taken care.
-
6:04
All employees use this to say what they're doing.
-
6:07
This is kind of how we're showing what's happening.
-
6:11
And all employees can also refresh the dashboard, right.
-
6:16
That's what we're building here, so
-
6:17
they'll announce that they're gonna refresh that.
-
6:19
But because we've used an abstract class here we can pretty easily add new
-
6:24
employee types should we need them for whatever simulation.
-
6:27
So in fact, let's see what other types are available.
-
6:30
So if we come in here.
-
6:32
We looked at server already, let's take a look at assistant.
-
6:36
So assistant is the person who is bussing tables and making things all ready for
-
6:40
our next guest.
-
6:41
Now see what happens as they flip the status.
-
6:44
And then the time passes, then they flip the status.
-
6:47
Okay, so let's pop back to our simulator method here.
-
6:51
And let's take a look at the loop.
-
6:53
So things are gonna live about 30 times.
-
6:55
We've found through testing that this is about the right amount of times that you
-
6:59
wanna show a demo to a client.
-
7:01
So we'll do that 30 times.
-
7:04
And the first thing that we're gonna try to do here is get ahold of an available
-
7:08
server.
-
7:09
So we're gonna again use streams.
-
7:11
And streams, we're gonna filter out any server that's available and
-
7:14
we're gonna say find any.
-
7:16
Now it's possible that there is no server that's available, right?
-
7:19
And that's what this optional is about here.
-
7:21
This optional is saying the possibility of an available server exists.
-
7:26
An optional produces a way to protect against nulls.
-
7:31
And so what we can say is we say, isPresent, and that's basically doing
-
7:34
a null check, but if the server is present then we're going to go ahead and
-
7:38
get the server from the optional.
-
7:40
So that's how you access and that's how you protect against it.
-
7:43
And we've done the same thing for the assistant here, so the assistant,
-
7:46
is the assistant available, find any.
-
7:48
And if they are present,
-
7:49
get the assistance, and then refresh the dashboard with them.
-
7:53
Okay, and then what we're gonna do is we're gonna loop through
-
7:55
each of the tables that we have available.
-
7:59
And then we do a switch statement on the status to see each one of these
-
8:04
states that it's in.
-
8:05
And we do the different bits based on who should be working on things.
-
8:08
So if we do have an available server,
-
8:10
we lead them to the table when it's available.
-
8:12
When it's finished, we close out the table, if again, if somebody is available.
-
8:16
And when the table needs bussing, the assistants take care of it.
-
8:20
And then we have a final pass time here in our loop, so
-
8:23
that we don't just bomb the console with output.
-
8:25
We want to make it take a little couple beats, so it'll run about for
-
8:27
thirty seconds.
-
8:29
And finally we want to close up shop on the loops over, right?
-
8:33
So we need to have everybody clock out, that will help this threads that
-
8:36
are running to stop and we're going to shut down the dashboard finally.
-
8:41
All right, you ready to kick this off.
-
8:42
Let's see what happens.
-
8:43
So if you come up here in the Simulator, if you just click
-
8:46
over here this little play button, we're gonna say, Run 'Simulator.main()'.
-
8:50
And here we go, it's starting to kick things off.
-
8:53
So I'm gonna scroll to the top and it's going to keep on filling out.
-
8:56
So what we can see is that Alice has looked at the dashboard.
-
9:01
She's available, so she refreshed it.
-
9:02
She said, she's Alice, she's gonna be your server, follow me to table 1, and
-
9:05
she's got them sat down already.
-
9:07
And then Bob's going to go ahead and he's available, so
-
9:09
he's going to refresh the dashboard.
-
9:11
He's going to say, hi I'll be your server, take me to number 2.
-
9:15
Alice says here's your menus and
-
9:16
then now she's available again she's going to refresh and you'll see that
-
9:19
the tables are now occupied that we can see that from our dashboard.
-
9:23
And bob gives the table the menus.
-
9:27
Bob says follow me to your table.
-
9:30
Alice is now available.
-
9:33
Here's some menus.
-
9:34
And we're showing this to the client.
-
9:36
This what the client is liking to see.
-
9:38
Watching this say that, they're doing a lot of refreshing aren't they?
-
9:42
And Bob says, follow me to your table.
-
9:45
And he says, how come nobody's checked out yet?
-
9:48
So we're still going.
-
9:50
We're gonna get all the tables set.
-
9:53
Bob, we got 5, Charlie's available.
-
9:58
Charlie's refreshing the dashboard.
-
10:01
Here we go.
-
10:06
Four of the tables are finished.
-
10:07
None are available, so now finally We need to get some people in there?
-
10:15
And get the money.
-
10:17
So Bob says, here's your bill for number 1.
-
10:21
That was Alice's table.
-
10:23
Hm?
-
10:26
So now it says finished.
-
10:29
Moving through.
-
10:31
Here comes Charlie.
-
10:31
He's cleaning stuff up and now the table's available again and
-
10:34
we can start the whole process again.
-
10:36
So we're kind of showing off what this dashboard is doing and
-
10:40
the client does notice a couple things right off the bat as a we're showing him.
-
10:45
And he says he doesn't like how much time his staff is refreshing the dashboard,
-
10:50
he thinks that they won't like that.
-
10:51
So I say, is it okay if I take some notes and we'll come back later and
-
10:54
we'll clean this stuff up for you.
-
10:56
So I've got Trello up in here and
-
10:58
I'm gonna start taking some notes on what they said.
-
11:01
So he says that the staff will not like needing to refresh the dashboard,
-
11:06
he says, that is too much.
-
11:10
He also pointed out that the servers seem to be collecting each other's tips.
-
11:15
[LAUGH] And they're definitely not going to like that, right?
-
11:17
So he says, the way that he'd like to run things, or
-
11:20
that servers should be assigned a table and I guess that makes sense.
-
11:28
And the other thing that he notices is there seems to be a priority
-
11:31
towards available tables versus people who have already been sitting there.
-
11:35
So, he does not like that.
-
11:37
He says, prioritization seems to favor availability.
-
11:42
And not the guests that are waiting for their check, he said,
-
11:44
we need to remember that guests that are there occupying the tables.
-
11:50
We need to get their bills turned around quicker, which is true we saw that right?
-
11:53
And other than that he loves this and he's wondering if there's something else that
-
11:57
we can offer that helps keep guest ready, right?
-
12:00
A lot of time is missed trying to find the proper guest who put their name on
-
12:03
the list, right?
-
12:04
So, we do in fact offer a client solution that uses one of those pagers, right?
-
12:08
When the table's ready, the pager buzzes.
-
12:11
So here I'm going to show off that pager opportunity.
-
12:14
Have you ever seen those where the thing buzzes and it's like, whoah, okay here.
-
12:18
So we'll show that off.
-
12:20
He also mentioned that he'd like to add other staff in different states and
-
12:24
in our current state of affairs, this isn't very extensible.
-
12:27
I can't very easily change the logic to the client specific wants.
-
12:32
I also have a couple of other demos later today and I don't want multiple copies of
-
12:35
this code out there nor do we have time to hack several these demos together.
-
12:39
So I feel like we need a different way of thinking of things to be able to pass
-
12:44
all these little added bits in.
-
12:46
It's like, we want the servers an assistance or our dashboard or
-
12:49
even our new pager to watch, or observe, the state of the table.
-
12:55
Wait a second.
-
12:56
Are you thinking what I'm thinking?
-
12:57
Should we be using the observer pattern?
-
13:00
What do you say we use it?
You need to sign up for Treehouse in order to download course files.
Sign up