Last active
November 20, 2018 20:52
-
-
Save MHerszak/7da2d353d53b91f4644ac9dfdeac1f14 to your computer and use it in GitHub Desktop.
Build a SOLID command pattern in Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Command Interface | |
* @param {*} state | |
*/ | |
const CommandI = (state) => ({ | |
type: 'CommandI', | |
execute: (...rest) => state.execute(...rest), | |
}); | |
/** | |
* Receiver Interface | |
* @param {*} state | |
*/ | |
const ReceiverI = (state) => ({ | |
type: 'ReceiverI', | |
process: (...rest) => state.process(...rest), | |
}); | |
/** | |
* | |
* @param {*} receiver | |
*/ | |
function OnCommand(receiver) { | |
// Prepare proto | |
const proto = { | |
type: 'OnCommand', | |
// Execute add addition method | |
execute(...rest) { | |
return receiver.process(...rest); | |
} | |
}; | |
// Add | |
const basics = CommandI(proto); | |
// Greate object and return functions | |
return Object.freeze( | |
Object.create(basics) | |
); | |
} | |
function Invoker(command) { | |
// Prepare proto | |
const proto = { | |
type: 'Invoker', | |
// Execute add addition method | |
execute(...rest) { | |
return command.execute(...rest); | |
} | |
}; | |
// Add | |
const basics = CommandI(proto); | |
// Greate object and return functions | |
return Object.freeze( | |
Object.create(basics) | |
); | |
} | |
function Addition() { | |
// Prepare proto | |
const proto = { | |
type: 'Addition', | |
// Execute add addition method | |
process(a, b) { | |
return parseInt(a) + parseInt(b); | |
} | |
}; | |
// Add | |
const basics = ReceiverI(proto); | |
// Greate object and return functions | |
return Object.freeze( | |
Object.create(basics) | |
); | |
} | |
function Subtraction() { | |
// Prepare proto for specific implementation | |
const proto = { | |
type: 'Subtraction', | |
// Execute add addition method | |
process(a, b) { | |
return parseInt(a) - parseInt(b); | |
} | |
}; | |
// Subtraction | |
const basics = ReceiverI(proto); | |
// Greate object and return functions | |
return Object.freeze( | |
Object.create(basics) | |
); | |
} | |
function CalculatorContext(operation) { | |
const numberHistory = []; | |
const commandHistory = []; | |
let currentCommand = null; | |
let currentDisplay = 0; | |
function evaluateAnswer(...rest) { | |
commandHistory.push(operation); | |
const returnVal = operation.execute(...rest); | |
numberHistory.push(currentDisplay); | |
currentDisplay = returnVal; | |
} | |
return Object.freeze( | |
Object.create({ | |
execute: evaluateAnswer | |
}) | |
); | |
} | |
const additionCommand = OnCommand( | |
Addition() | |
); | |
const subCommand = OnCommand( | |
Subtraction() | |
); | |
const add = CalculatorContext( | |
Invoker(additionCommand) | |
); | |
const sub = CalculatorContext( | |
Invoker(subCommand) | |
); | |
add.execute(1, 2); | |
sub.execute(3, 4); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment