Created
September 20, 2018 07:04
-
-
Save sachioross/ce82cf5ed2cd8c2eb2d34137d58be082 to your computer and use it in GitHub Desktop.
Quick refactoring example showing usage of method overrides and dynamic injection.
This file contains 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
/** | |
* 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