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
Java 8 makes functions a first class citizen. Look at how quickly the pattern can be applied by embracing them.
Learn more
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
We saw the power of rapidly being
able to implement the pattern
0:00
by looping through subscribers
using our parameter as list.
0:03
Well there is, in fact, a growing
movement to make that even quicker.
0:07
Functional programming has been around for
a long time, but
0:10
it's relatively new to the Java world.
0:13
So there are newer patterns forming
that are leaning on this powerful,
0:15
succinct approach.
0:18
Let's give it a whirl.
0:19
If you haven't played around with Java 8's
functional programming side of things,
0:22
I hope that this example will
encourage you to explore it a bit.
0:25
Now our final project for this workshop is
going to explore an Olympics tracking app.
0:29
So we have a class called
GoldMedalReporter.
0:33
Let's open that up.
0:37
So under gold-watcher here,
there's GoldMedalReporter, and
0:38
it's a pretty bare bones class, right?
0:42
It's just for demo purposes,
0:44
it has a single method,
it's called reportWin, and basically,
0:45
it just says the gold medal was awarded to
whatever country was best at it, right?
0:49
So, we have all these other tools that we
would like to integrate with this, right?
0:53
So, over here under tools, we have this,
what is a Twitter client called Tweeter.
0:57
You can imagine that this can x
out to the API, but basically,
1:02
it takes whatever message was
passed out and sends it to Twitter.
1:05
There's also an LED light bulb that's
here and you pass in an array of colors.
1:09
It's using this var args pattern, so what
happens is an array will come in here, and
1:14
then we're going to use a Java
8 stream to collect and
1:19
make it comma-separated, basically.
1:23
More in the teachers notes on
that if you're interested.
1:26
And finally, we have one of these huge
screens that gets fans all worked up,
1:29
called a MegaTron.
1:33
And basically,
1:35
whatever you pass in, it says,
Let's hear it for whatever was passed in.
1:36
Yeah, MegaTron.
1:39
Such a funny name for that,
that that stuck, MegaTron.
1:41
So, anyway, the method here just roots for
whatever you give it, right?
1:45
So, what we want, we want all
these different tools to do their
1:49
thing when a gold medal happens, right?
1:53
When one of these wins are reported,
we want these tools to do their thing.
1:55
Now it's a fairly specific to the tool
type of method that we want to
1:59
take off, right?
2:03
Now we could do this by
creating a base class, and
2:04
maybe we could mix in the adapter
pattern and make them all look similar.
2:07
Or we could create a specific function for
our use case.
2:11
So let's try that first.
2:16
So In the GoldMedalReporter, right,
2:18
we want to first create a way to
add an observer-like function.
2:21
Okay, so let's do that, let's just say
2:27
public void, and we'll say addObserver.
2:32
The observer that's gonna be added
here is like we just talked about,
2:38
it's a specific function.
2:41
So Java 8 introduced the concept
of functional interfaces,
2:43
which allows you to specify
an expected method signature.
2:47
So what we're gonna do is we're gonna
use a functional interface that expects
2:51
a single string pattern and
returns nothing.
2:55
So that type of interface
is called a consumer, and
3:00
its type here that you specify
is what the first parameter is.
3:04
So that was a string, and
we'll call this observer.
3:08
Now we want to provide an easy
way to remove these, so
3:21
the typical implementation in removing
these is by passing in the observer.
3:24
But, we are going to be
providing probably a lambda or
3:29
an anonymous function, so removing it
by value is gonna be a little tricky.
3:33
So let's have the registering of
observers need to add a key as well.
3:38
So we'll say String key.
3:42
So you'll name it and
3:47
then pass in the function, so
it's like naming an anonymous function.
3:49
So we have a key and
a value that we want to store.
3:53
That sounds pretty much like a map to me.
3:55
So let's add a new class up here, we'll
say private map, and it's gonna be String,
3:58
which is the name of the function that
we're going to give it, and Consumer.
4:03
This is the values, right?
4:08
So the value is going to be
Consumer that we talked about.
4:09
It is a Java util map, and
we'll call it observers.
4:12
And we'll say new HashMap.
4:17
Cool.
4:20
So now in our addObserver what
that looks like is observers.put,
4:23
and we'll pass in the key and
the observer.
4:30
Here we go.
4:35
So now our map is of name to function.
4:37
And we could very easily
now remove as well.
4:41
Right, so we'll say public void
removeObserver(String key) and
4:44
we'll say observers.remove,
and you pass it a key.
4:52
And now we've got registering and
unregistering of functions.
5:01
Now we need to notify the observer.
5:04
Let's make it clear, right?
5:07
Let's let people know that we're
using the observer pattern.
5:10
So we'll say, notifyObservers.
5:13
And that's gonna take the country, right?
5:17
That's the string that we wanna pass in.
5:19
We're gonna pass in a country.
5:20
And all right, so we have a map.
5:23
And the values of the map are functions,
right?
5:26
So observers.values.
5:29
And for each of those, so
we'll get back a function.
5:33
And we want to call the method
that was passed in, and
5:39
for a consumer,
that's called accept, right.
5:44
And the reason why it's called accept
is because it accepts the value that
5:48
was passed in,
which in our case is gonna be country.
5:52
So in our reportWin, let's just go
ahead and we'll say notifyObservers,
5:59
and we'll also pass in the country there.
6:03
Cool, so again, this is gonna loop through
each of the functions that were passed in,
6:06
for each of the functions that's going to
call the function, passing it the country.
6:10
Awesome, so
let's do the Twitter one first.
6:14
So let's pop back into the examples here,
and we have a reporter object,
6:17
so I'm gonna say reporter.addObserver,
and let's call this observer tweet.
6:23
I think that makes the most sense.
6:30
So we could get that key out later.
6:32
And now it's asking for
a consumer, and remember,
6:34
a consumer is a method that takes
a string and returns nothing.
6:36
So we should be able to just say country.
6:42
Now because this is a lambda,
6:45
there is only one value we
don't need to parentheses.
6:47
We're gonna say Tweeter.tweet and
let's see,
6:50
we'll say country, Just won the Gold!
6:55
#olympics.
7:03
And it doesn't know what Tweeter is,
so there we go.
7:07
Let's see if we can make this a prettier.
7:11
Screen is pretty tiny, let's do this, too.
7:14
Bring that up on one line here, and
we'll put a semicolon at the end.
7:21
Okay, awesome.
7:25
So we've added observer, that will take
a country and then call the tweet.
7:26
So let's do the next one.
7:30
Let's do the Megatron.
7:32
So the key is definitely
gonna be megatron,
7:33
addObserver megatron.
7:39
And basically all we want to do,
remember, this one just cheers for
7:43
whatever was passed in.
7:47
Basically, all we want to do is just
pass in country to this method, right?
7:48
So because the method signature of that
display method is actually a consumer,
7:51
right, it's actually the same.
7:56
A method that returns nothing and
7:59
accepts the string, we can just
use the method reference, right?
8:01
So if I do megaTron:: that says,
8:04
I'm talking about a specific method,
and the method is display.
8:08
So what that will do is it will,
when it's observed,
8:13
it will pass the value into this instance.
8:16
Pretty cool, right?
8:19
Okay, and finally let's go ahead and
8:22
add an observer for our lights, LED light.
8:25
So, it's gonna take a country.
8:30
And we have a lights variable here.
8:34
So I wanna say light.flashColors.
8:36
And we need to access another
method that's outside of this,
8:40
but that's okay, right?
8:45
We can call methods from
inside of a lambda, so
8:46
we'll call colorsByCountry.get country,
8:48
and we'll hope that
whatever is passed matches.
8:54
Right now it's only USA and Brazil.
8:57
Other countries do matter, I just
didn't take the time to fill that out.
9:00
Just so you know, everybody, you matter.
9:03
And I just wanted to point out that
these methods could be as complicated
9:07
as we need.
9:10
But most of the time, they would probably
end up looking a lot like this, right?
9:11
They're pretty small little methods.
9:14
No new classes, very light interface, and
9:16
we did a good job of conveying that
these are in fact observers, right.
9:19
We have all this addObserver language.
9:23
Let's go ahead and let's run this.
9:25
So I'm gonna click this Run
'Example.main()', and boom,
9:28
the gold medal has been
awarded to the USA.
9:33
Let's hear it for the USA.
9:35
USA won the gold, #olympics,
flashing red, white and blue.
9:36
Awesome, right?
9:40
We just went for the gold and we won.
9:41
So keep your eye out for
9:43
more patterns being applied in
this more declarative style.
9:45
Do remember that these
functions are closures, right?
9:48
So any value that's put in here will
be captured, will be closed over.
9:51
So this approach, as well as the last one,
will keep objects alive and
9:57
safe from garbage collectors.
10:01
So it's very possible to cause
a memory leak if you aren't careful,
10:04
of removing observers when
they're no longer needed.
10:07
So what do you think?
10:10
Pretty quick to implement, isn't it?
10:11
So now that you've seen the evolution
of this pattern over time,
10:13
I hope you've got a really solid
understanding of why you should use it,
10:16
as well as how to make the magic happen.
10:20
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