- [Narrator] In the last lesson we introduced
the strategy design pattern and discovered how
we could work with it.
In this lesson we're going to implement the pattern
by creating several log strategies in a single class.
So, the first thing we want to do is encapsulate all
of our strategies, all of our algorithms in a single class
in a single file.
So I'm going to go over here to the start folder.
We are in the exercise files for chapter four,
chapter four lesson 11 and within that start folder
we have the index code that we changed to use
the change strategy on line seven as well as the config.json
file where we are able to set the strategy before
the application gets started.
So let's go ahead and add another file to this
called log strategy.js and what we want to do in this file
is create a class that we call log strategy
and we're never going to instantiate any objects
with this class.
What we're going to do is just save several static methods
to this class and each static method that we add
to this class will be a different strategy.
So let's go ahead and add a static no date.
That's one of the strategies that we have to handle.
We also need a static to file.
So one of the strategies that we have to handle.
We should also have the logger work as it currently does,
so just a static to console.
We'll call the current way the logger works to console
and then it's also a good idea to add a none
meaning no strategy.
So if we were to set the strategy to none
we wouldn't see any logs at all.
So these are the four strategies
that we're going to start with.
So let's just go ahead and code them.
I'm going to go ahead and include the path
and the file system, append file to append our log file,
so if we want to use that.
So we'll grab that method from the file system
and we'll just go ahead and do this top down.
So we will start with the no date strategy.
So each of these strategy functions need to receive
the payload of data, the information that we should
actually be logging.
That consists of a time stamp and a message.
So for the no date log strategy to work all we're going to
go ahead and do is log the message without the time stamp.
Let's go ahead and handle the to file strategy.
So again each of these strategies are going to get time stamp
and message and for the to file as opposed to using
the console log what we're going to do is we will create
a variable for the file name of where we're going to add
the logs.
So we'll do it in this directory.
So I'll use a path.join underscore underscore dir name
and we will also use logs.txt.
So we'll go ahead and put all of our logs
inside of the logs.txt file found in this directory
and then we can go ahead and call append file
and we'll give them the file name which is actually
the full file path and now the code that we want to add
to this file.
So we want to add the time stamp, a little dash,
along with the message, and a new line
so that each log appears on its own line.
So once we're done appending that file we can see
if we have any errors that occur during the append file
process and we'll go ahead and handle those.
So if there was an error with this log file
we'll just let our user know about it.
Error writing to file, and then I'll also go ahead
and throw the error itself to the console
using console.error.
Great, so that handles our to file strategy.
We also need to handle our basic strategy,
the one that the logger currently uses, the to console.
So we are just going to go ahead and log with to console
the time stamp and the message.
Time stamp dash message.
Great, so now we have created three log strategies
and it's time to incorporate these log strategies
into our logger.
So let's go over to the logger.js file
and from this file what we're going to do is we're not
going to actually console log directly.
We want to use a strategy.
So here on line 14 within the log method I'm going to say
this.strategy.
So the strategy's going to become a function that will
represent one of those four log strategies.
So we want to make sure that we send the time stamp
in the message to whatever the strategy method is.
And then when we actually create a new instance
of the logger I can set the strategy.
This.strategy, we will start out with,
we better import our log strategies.
Require log strategy and now I can use them.
So inside of the constructor I'm going to go ahead
and set the first log strategy to no date,
or actually, for the fun of it we'll set it to what
it currently is, so we'll set the first log strategy
as log strategy to console.
So that means that this.strategy is going to reference
or point to the log strategy to console method,
meaning that whenever we actually do a log
the logger will log the message and the time stamp
to the console.
So we also have to implement a change strategy
or a method that allows us to dynamically change
the logging strategy.
So I'll do change strategy and we want to get
a new strategy as the argument that we send
to the change strategy function
and then we're going to say this.strategy is equal
to the log strategy and we will use the new strategy
that we would like to change it to.
Great, so that's how we can change the logging strategy
to a different strategy at run time.
Let's go ahead and take a look at our application.
Let's go to the terminal and try to run it.
Node index.js, and we can see that we have three logs.
That's good.
If we look at index.js we do have three logs
and all three of these logs are supposed to be using
the console strategy and if we look at that
we have the time stamp in the log actually showing up
in the console but look at this.
We changed the strategy on line seven
and we have three more logs.
So they went into the file because at line seven
we changed the strategy and now all of our logs
after line seven are going to be logged to the file.
Something else that we need to do is we need to
make sure that when we start our application we're not
setting the log strategy based on to console
on line seven.
We actually want to pull that information from
the configuration file.
So inside of the logger I'm also going to import the config
and from the configuration file when we actually use
the constructor we'll also set the log strategy.
So we'll add strategy, so we can send the log strategy
to the constructor and we might as well default
this to what we currently want to use which is to console.
So that's what we're currently using as the strategy
and I'm going to go ahead and add the brackets
so we can use the string to select the appropriate field.
So now if you create this logger without sending it
any sort of a strategy we're going to log to the console.
But what I'm going to do since I have the config coming in here
is I'm going to come down to where we instantiate the logger
right before we export it here on line 27
and I'm going to say config.logs.strategy.
So we send the logging strategy from the configuration
file to the new logger.
If we look at the configuration file that strategy
is no date.
So if I come over to the terminal and run the file
this time we actually see the first three logs
now with the no date strategy.
So we're just seeing the message,
we're not seeing the time stamp,
and we can see that we also are
still logging to the console.
So because we ran this file twice we have written
an additional set of logs to the console
because in our index.js nine, 10, 11, and 12 does so.
Now what I love about the log strategy pattern is
it's built to grow.
So if we wanted to add additional strategies to our
application later we could do so without ever having
to touch the logger.js file.
So I'm going to go into the log strategy
and we're going to create one more strategy really quickly
and this strategy is going to be called to Morse Code
and to Morse Code is going to take in a time stamp
and a message and we want to log this message to Morse Code.
So we're going to rely on NPM to do so.
I'm going to come over here to my terminal
and we will NPM install a NPM called Morse.
We can actually use this Morse package to convert
text to Morse Code.
If you don't have a package JSON as I don't
'cause we're just doing a quick sample here
you might see this error.
That's not a problem.
When I did the NPM install it looks like we picked up
our Morse and its dependencies and I've placed them
in the node modules folder.
So what I'm going to do is I'm going to make sure
we include Morse 'cause we're going to use that
and for our to Morse Code log what we're going to do is
get the Morse Code.
So Morse.encode is the NPM method that we can use for that.
We'll pass it the message and then now that we have
the Morse Coded version of the message I can go ahead
and add a console.log Morse Code, there we go,
and this is neat.
I should be able to come into my configuration JSON file
and change the strategy to Morse Code.
That's the name of the strategy.
Now when we run this application we should see
the very first three logs logging to Morse
and then I'm going to go ahead and change the strategy
for the second three logs to none or no strategy
and just to make sure we see that work I'll go ahead
and also delete the logs.txt file.
All right, let's go ahead and give it a shot.
Coming over the terminal, clear out this stuff.
Node index.js, and now we can see our log messages
as Morse Code.
Because we set the log strategy to none for the second set
of logs that means we shouldn't see a file or we shouldn't
be using that to file log strategy.
So we're able to set the log strategy to whatever we want.
We can set up a default strategy in the config JSON
document, and we can load that when we start
our application or we can even change our strategy
dynamically at run time allowing us to change
the logging strategy based off of user input
or some sort of data parameter.
So, that's the strategy pattern.