Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
The Command Pattern is usually implemented using classes. However, it can easily be achieved in a functional pattern.
Normally all command objects with the same interface can easily be swapped as needed. This is one of the main benefits of the command pattern.
For example, if you wanted to send an email, but wanted to implement a way to change between sending the email via Sparkpost or through AWS, you would do something like the following:
class IEmailCommand { constructor() {} execute(sender, receiver, subject, body) { throw new Error('Not implemented'); }}
class SparkPostEmailCommand extends IEmailCommand { constructor(apiKey, SparkPost) { this.sparkpost = new SparkPost(apiKey); } execute(sender, receiver, subject, body) { return this.sparkpost.transmissions.send({ content: { from: sender, subject, html: body, }, recipients: [ {address: sender} ] }); }}
class AWSEmailCommand extends IEmailCommand { constructor(AWS) { this.ses = new AWS.SES(); } execute(sender, receiver, subject, body) { return new Promise((resolve, reject) => { this.ses.sendEmail({ Destination: { ToAddresses: [receiver] }, Message: { Body: { Html: { Data: body, }, }, Subject: { Data: subject, } }, Source: sender, }, (err, data) => { if (err) reject(err); resolve(data); }); }); }}
Now we can use the SparkPostEmailCommand and the AWSEmailCommand interchangeably:
const command = new SparkPostEmailCommand(myApiKey, SparkPost);command.execute('us@email.com', 'them@email.com', title, body) .then((data) => console.log('success')) .catch((err) => console.error('failure', err));
But most Command objects are just two methods: a constructor and an execute method (and sometimes an undo method). It almost feels like when we call the constructor, we are just delaying the execution of the execute method until we want it do perform its side-effect.
Using Higher Order Functions
To me, this would be a great time to use higher order functions to simplify the code above and remove the need for classes in favor of simple functions.
Since most of the time, all we care about is setting up some dependencies, and then delaying execution, we could just write our Command classes as functions:
const sparkPostEmailCommand = (apiKey, SparkPost) => { const sparkpost = new SparkPost(apiKey); return (sender, receiver, subject, body) => { return sparkpost.transmissions.send({ // Same as above }); };};
const awsEmailCommand = (AWS) => { const ses = new AWS.SES(); return (sender, receiver, subject, body) => { return new Promise((resolve, reject) => { // Same as above }); };};
And now, instead of creating new objects, we can just use the command as functions:
sparkPostEmailCommand(myApiKey, SparkPost)('us@email.com', 'them@email.com', title, body) .then((data) => console.log('success')) .catch((err) => console.error('failure', err));
Or we can delay execution:
const execute = sparkPostEmailCommand(myApiKey);// do some workexecute('us@email.com', 'them@email.com', title, body);
Why Use Higher Order Functions?
While classes in other languages would give you some type hinting and safety, the same isnât true in JavaScript. You canât really know that all the signatures for your executemethods all look the same unfortunately.
And without the typing, thereâs no real need to add all the bloat that comes with the class implementation. Why worry about the this binding? Or the extends BaseCommand ?
The point of using these design patterns isnât that they need to be object oriented. Itâs that they help you organize your code using common patterns. Building an object with dependencies and then doing something is a common pattern, where âdoing somethingâ may be done in different ways.
If your team is used to classes and objects, then use classes and objects.
If your team is used to functional programming, then know that design patterns like the Command pattern can be used in a functional way as well.
Ivan Montiel is the founder and CEO of Clarity Hubâââa company that integrates with Intercom to give your Customer Success team real-time suggestions when helping customers.You can follow him on Twitter.
The Command Pattern Using Higher Order Functions was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.