Skip to content

Instantly share code, notes, and snippets.

@sachioross
Created September 20, 2018 07:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sachioross/ce82cf5ed2cd8c2eb2d34137d58be082 to your computer and use it in GitHub Desktop.
Save sachioross/ce82cf5ed2cd8c2eb2d34137d58be082 to your computer and use it in GitHub Desktop.
Quick refactoring example showing usage of method overrides and dynamic injection.
/**
* Examples of function and object overriding
* in addition to dynamic dependency injection.
*
* If you want proof this works, just take this gist,
* put it into a file (e.g. "test.js") and then run
* `node test.js' followed by `node test.js new`
*/
/*
We started with the following users object,
and the #getUserName and #main functions:
*/
users = ["Rick", "Morty"];
function getUserName(name) {
for (var i = 0; i < users.length; i++) {
if(users[i] === name)
return users[i];
}
}
function main(userToFind) {
console.log(getUserName(userToFind));
}
console.log("\nBEFORE REFACTOR");
main("Rick"); // This will print "Rick"
/*
What we want to do: change our users to an object,
like the 'newUsers' below:
*/
newUsers = [
{
name: "Morty",
lastName: "Smith"
},
{
name: "Rick",
lastName: "Sanchez"
}
]
/*
We also want to change the output to display the _full name_
How do we limit what we're touching? Override only the
parts that need modification: #getUserName
*/
getUserName = function(name) {
for (u in newUsers) {
if (newUsers[u].name === name) {
return newUsers[u].name + " " + newUsers[u].lastName;
}
}
}
console.log("\nOVERRIDDEN #getUserName");
main("Rick"); // Prints "Rick Sanchez"
/*
We didn't have to touch #main, but we now have to manage
two different variable names through two separate functions.
We can fix that by simply introducing a local variable and
using a dynamic injection pattern.
In the below example, _oldConfig_ and _newConfig_ are
simply declarations, while _config_ is actually the object
that will be utilized by our #getUserName function.
*/
const oldConfig = {
users : ["Morty", "Rick"]
}
const newConfig = {
users : [
{
name: "Morty",
lastName: "Smith"
},
{
name: "Rick",
lastName: "Sanchez"
}
]
}
let config = oldConfig;
getUserName = function(name) {
let users = config.users;
for (var i = 0; i < users.length; i++) {
if(users[i] === name)
return users[i];
}
};
console.log("\nINJECTABLE CONFIG OBJECT")
main("Rick"); // Prints "Rick"
config = newConfig;
getUserName = function(name) {
users = config.users;
for (u in users) {
if (users[u].name === name) {
return [users[u].name,users[u].lastName].join(" ");
}
}
};
main("Rick"); // Prints "Rick Sanchez"
/*
All we had to do was change which declaration the
_config_ object referenced. This still doesn't
address our other problem of making the
#getUserName function available in both scenarios.
BUT, we can solve this by doing the same thing we
did with _users_ and adding #getUserName to the config
object and making and adjustment to the #main and #getUserName signatures
*/
oldConfig.getUserName = function(name, config) {
let users = config.users;
for (var i = 0; i < users.length; i++) {
if(users[i] === name)
return users[i];
}
};
newConfig.getUserName = function(name, config) {
users = config.users;
for (u in users) {
if (users[u].name === name) {
return [users[u].name,users[u].lastName].join(" ");
}
}
};
main = function(userToFind, config) {
let getUserName = config.getUserName;
console.log(getUserName(userToFind, config));
}
// By making the above changes, we can have our flag be at the very beginning:
if(process.argv[2] === "new") {
config = newConfig;
} else {
config = oldConfig;
}
console.log("\nDYNAMIC SELECTION / INJECTION");
main("Rick", config);
/*
Trust me, this can be improved a lot further. Ideally
you work on this to avoid having to change a whole
chain of signatures just to add dynamic configuration injection.
But, being as it was late when I wrote this and I wrote
this fairly quickly, you get the above example.
*/
console.log(`${config.getUserName("Morty", config)} says HTH!`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment