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