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
The casting and not being able to write your own Observable class properly has led to developers looking outside of the provided implementation. Turns out it's pretty straightforward.
Learn more
-
0:00
Okay. So let's walk into another common scenario
-
0:02
that you'll encounter in your development travels.
-
0:04
Now, you'll definitely see this homegrown style implemented in other code bases, and
-
0:08
most likely, you'll have the temptation to do it yourself.
-
0:11
Okay. So,
-
0:12
I've got a pretty straightforward example that we can use to create that,
-
0:16
hey, I should use that observer pattern, feeling.
-
0:19
Now, the idea is that we have a universal remote control.
-
0:22
One of these that controls all sorts of devices.
-
0:24
I think if we just focus here on the power button, we can get there pretty quickly.
-
0:28
When I press the power button, I want all the devices on this control to turn on.
-
0:32
Let's take a look at some proof of concept code for remote control.
-
0:36
So, let's open up the universal remote module right here, right?
-
0:41
So in the source directory here,
-
0:44
you'll see that we have com team treehouse remote, and there's a devices package.
-
0:48
Let's take a look at our Blu-Ray player here.
-
0:51
Let's open this up.
-
0:51
So, it has some methods on it, and it extends the abstract class device.
-
0:57
And device has it announce, and it has the ability to toggle power.
-
1:02
So, every device is able to be powered on and off.
-
1:07
So, let's see what else extends this.
-
1:10
So, we have a stereo, and the stereo has the volume up and
-
1:15
down, and it also has the power on and off, because the device.
-
1:18
So, what else do we have here?
-
1:19
We have the remote control itself, let's take a look.
-
1:21
So, the current implementation.
-
1:24
Okay, it takes two of the devices that we have talked about, and
-
1:28
it stores them for later.
-
1:31
Yes, that works, and it also calls when it calls press power button,
-
1:38
it calls the toggle power on each of those devices that it has.
-
1:42
Okay, so let's look at application here.
-
1:45
So, it creates the two passes, and then the remote control,
-
1:48
and it presses the power button a couple times just to make sure it works.
-
1:51
Let's go ahead, I'm going to click this and choose run application main.
-
1:56
And in fact, it does, it powers that on, the Blu-Ray player gets powered on, and
-
1:58
press it off and then power it off.
-
2:01
Okay, cool.
-
2:01
It works.
-
2:03
Now, I just bought a new Apple TV, and
-
2:06
I'm pretty excited about it, but I don't want another remote.
-
2:09
So, I'm just going to install it here.
-
2:13
How am I going to do that?
-
2:15
So, that means in order to add it, I'm going to have to modify this remote
-
2:19
control file, or I'm going to have to add it to the constructor, and
-
2:23
that's kind of gross, isn't it?
-
2:26
There's a software design principle that states a class should be open for
-
2:30
extensibility, but closed for modification.
-
2:32
Now, this is the Open Closed Principle that the teacher's notes for more.
-
2:36
Now, if we have to add that Apple TV to the constructor, and
-
2:40
save a new type, we'll be modifying that class, and
-
2:44
we'll do that every time we want to add a new device.
-
2:47
That's gross.
-
2:48
I mean, what if other people are using this remote control code?
-
2:50
We're going to have to be careful not to break their implementation.
-
2:53
I mean, I don't think that we want everyone to have to buy an Apple TV.
-
2:57
I'm sure Apple wouldn't complain, but still, we should make this class open for
-
3:01
extensibility.
-
3:03
Are you feeling it?
-
3:04
Are your observer ears burning?
-
3:06
We should make our devices observe the pressing of that button,
-
3:09
and we should allow them to register themselves, right?
-
3:14
So, we could create a new button class and make it extend Java util observable,
-
3:19
and then add an instantiated button to the class and
-
3:22
we could make our device implement observer.
-
3:24
But that seems like a little bit of overkill, doesn't it?
-
3:28
Why don't we just keep a list of devices and
-
3:30
loop through them one by one and turn on the power?
-
3:33
Should we give that a go?
-
3:35
Okay, so first in the remote control, let's get rid of this, and
-
3:39
let's get rid of the constructor too.
-
3:42
Let's just make a new list of devices here.
-
3:45
We'll say a private list of device, and we'll call that devices.
-
3:52
And we'll make that a new array list.
-
3:54
And a new character, and we'll make that new array list.
-
3:59
Okay, and
-
4:04
we'll add a method that will allow us to register a device.
-
4:08
So, we'll say public void device.
-
4:11
I want to take the device and
-
4:17
close the device.end device.
-
4:24
Finally, we'll just loop through those devices and call toggle power.
-
4:30
Right.
-
4:31
So let's try that.
-
4:32
So we'll say for device and device in devices.
-
4:38
I'll say device.toggle.
-
4:45
Now, in the application code, we just need to change this just a touch, right?
-
4:48
So we got rid of that constructor, let's get rid of this altogether.
-
4:51
And let's move this up to the top here.
-
4:54
So we'll make a new remote control.
-
4:56
We'll build those new things.
-
4:57
And then we'll say rc.addDevice.
-
5:00
And we'll add the Blu-Ray.
-
5:03
And we'll add the stereo.
-
5:07
And let's make sure that it's still working.
-
5:09
Let's run it.
-
5:12
And sure enough, it's still working, nice.
-
5:15
And now just to show off, let's make an Apple TV.
-
5:20
Happen to know that they're not as easy to make as this.
-
5:24
So, we'll make a new class, and the device is here called Apple TV.
-
5:31
And it's going to extend Device.
-
5:34
We could fill this out with whatever we want, but
-
5:37
because it extends Device, we can toggle the power.
-
5:42
Pop over here, and I am going to say,
-
5:49
[INAUDIBLE] AppleTv.
-
5:53
And we can just say rc.addDevice, tv.
-
6:00
And run this again, and boom.
-
6:03
Now, everything's powering on, and everything's powering off.
-
6:05
So, because we left that class open for extension, we could keep it closed for
-
6:10
modification.
-
6:11
Awesome, right?
-
6:11
That was so quick.
-
6:13
Wait a second, what do we do about the other buttons?
-
6:16
How could we do that?
-
6:20
Is observer going to work to turn the volume up and down?
-
6:23
This is working because the method names are the same, right?
-
6:26
All the devices have the same toggle power, but
-
6:28
not all the devices have volume controls.
-
6:31
Looks like it's time to start hitting the Design Patterns book and tutorials.
-
6:36
Another benefit of the home grown approach is that you can
-
6:39
fairly quickly test your assumptions an iterator to see if the pattern is
-
6:42
actually the solution you needing.
-
6:44
Now, this is the need to create additional classes as an implementations.
-
6:48
The parametrized types a specific method calls really help legibility.
-
6:52
However, it does lead to the problem of not specifying that you were,
-
6:55
in fact, using the observer pattern.
-
6:58
If you were in the know,
-
6:59
would you be aware that this code was using the observer pattern?
-
7:02
It is definitely something that we are giving up by not using the very explicit
-
7:06
observer interface.
-
7:08
A side benefit of using this approach is that it usually ends up leading you to
-
7:12
other patterns.
-
7:13
For instance, I'm pretty sure, thinking through the other buttons on the remote,
-
7:17
that we are looking for a few patterns here.
-
7:20
I think we should probably look into the command pattern.
-
7:22
Check the teachers notes for more thoughts on that approach.
-
7:25
Now, in the interest of rapidly prototyping and iterating, we should take
-
7:28
a look at what the functional approach to this pattern entails.
-
7:32
These are starting to gain momentum as the quickest way to prototype a solution.
-
7:36
Let's do that right after this quick break.
You need to sign up for Treehouse in order to download course files.
Sign up