๐ Junior Vs Senior Code - How To Write Better Code - Part 2 ๋ฅผ ๋ณด๊ณ ์ ๋ฆฌํ ๋ด์ฉ์
๋๋ค.
๐ Noob-Vs-Pro-Code - Github
Copy const readline = require("readline")
const readlineInterface = readline.createInterface({
input: process.stdin,
output: process.stdout
})
readlineInterface.question("What is your name? ", name => {
readlineInterface.question("What is your job? ", job => {
readlineInterface.question("How old are you? ", age => {
console.log("Hello " + name + ". You are a " + age + " year old " + job + ".")
readlineInterface.close()
})
})
})
Copy const readline = require("readline")
const readlineInterface = readline.createInterface({
input: process.stdin,
output: process.stdout
})
async function main() {
const name = await askQuestion(realineInterface, "What is your name? ")
const job = await askQuestion(realineInterface, "What is your job? ")
const age = await askQuestion(realineInterface, "How old are you? ")
console.log("Hello " + name + ". You are a " + age + " year old " + job + ".")
readlineInterface.close()
}
main()
function askQuestion(readlineInterface, question) {
return new Promise(resolve => {
readlineInterface.question(question, answer => {
resolve(answer)
})
})
}
Copy // async.js
const askQuestion = require("./askQuestion")
async function main() {
const name = await askQuestion("What is your name? ")
const job = await askQuestion("What is your job? ")
const age = await askQuestion("How old are you? ")
console.log(`Hello ${name}. You are a ${age} year old ${job}.`)
}
main()
// askQuestion.js
const readline = require("readline")
function askQuestion(question) {
const readlineInterface = readline.createInterface({
input: process.stdin,
output: process.stdout
})
return new Promise(resolve => {
readlineInterface.question(question, answer => {
resolve(answer)
readlineInterface.close()
})
})
}
module.exports = askQuestion
4. Single Responsibility Principle(SRP, ๋จ์ผ ์ฑ
์ ์์น)
SOLID: Single Responsibility Principle in JavaScript
"class(a.k.a module) ์ ์ค์ง ํ ๊ฐ์ง ์ด์ ๋๋ฌธ์ ๋ณ๊ฒฝ๋์ด์ผ ํ๋ค."
Robert C. Martin
SRP๋ ๊ฐ์ฒด ์งํฅ ์ธ์ด์ ๊ตญํ๋์ด ์์ง ์๊ณ , ํ๋กํ ํ์
์์์ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ์ ์ฉ๋๋ค.
ํ๋์ class๋ ์ค์ง ํ ๊ฐ์ง ์ฑ
์๋ง ๊ฐ์ ธ์ผ ํ๋ค(๋จ์ผ ์ฑ
์ ์์น )
Employee class๋ SRP ์์น์ ๋ฐ๋ผ ์ฌ๋ฌ class๋ก ๋ถ๋ฆฌ๋์ด์ผ ํ๋ค.
Copy // ๋์ ์์
// ๐ฃ ํจ์ ๋ณ๊ฒฝ ์ class ๋ด๋ถ์ ์ฝ๋ ๋ณ๊ฒฝ ํด์ผ ํจ
class Employee {
calculatePay() {
//...
}
reportHours() {
//...
}
saveToDB() {
//...
}
}
Copy // users.js
function createUser(user) {
return {
...user,
id: Date.now(),
createdAt: new Date(),
updatedAt: new Date()
}
}
function updateUser(user) {
return {
...user,
updatedAt: new Date()
}
}
module.exports = { createUser, updateUser }
// main.js
const { updateUser, createUser } = require('./api/users')
function saveUser(user) {
// ๐ซ validation
// ๐ซ error printing
const errors = []
if (user.username) {
if (user.username.length < 3) {
errors.push("Username must be 3 or more characters")
}
} else {
errors.push("Username is required")
}
if (user.password) {
if (user.password.length < 8) {
errors.push("Password must be 8 or more characters")
}
} else {
errors.push("Password is required")
}
if (errors.length > 0) {
errors.forEach(error => console.error(error))
return
}
// save users
if (user.id == null) {
console.log('Created User')
createUser(user)
} else {
console.log('Updated User')
updateUser(user)
}
}
const user = {
username: '',
password: 'password'
}
saveUser(user)
Copy // main.js
const { updateUser, createUser } = require('./api/users')
// 1๏ธโฃ
function saveUser(user) {
if(user.id == null) {
console.log("Created User")
createUser(user)
} else {
console.log("Updated User")
updateUser(user)
}
}
// 2๏ธโฃ
function validateUser(user) {
return [
...validateUsername(user.username),
...validatePassword(user.password)
]
}
// --- helper function (returns an array of errors) ---
function validateUsername(username) {
const errors = []
if(!username) errors.push("Username is required")
if(username != null && username.length < 3) {
errors.push("Username must be 3 or more characters")
}
return errors
}
function validatePassword(password) {
const errors = []
if(!password) errors.push("Password is required")
if(password != null && password.length < 8) {
errors.push("Password must be 8 or more characters")
}
return errors
}
// -----------------------------------------------------
const user = {
username: 'USER',
password: 'password'
}
// 2๏ธโฃ
const errors = validateUser(user)
if(errors.length > 0) {
errors.forEach(error => console.error(error))
return
}
// 1๏ธโฃ
saveUser(user)
Copy // validation.js
// 1๏ธโฃ
function validationMessages(validations, object) {
return Object.entries(validations).reduce((errors, [property, requirements]) => {
errors[property] = []
if (requirements.required) {
const errorMessage = validateRequiredMessage(object[property])
if (errorMessage) errors[property].push(errorMessage)
}
if (requirements.length) {
const errorMessage = validateLengthMessage(object[property], requirements.length)
if (errorMessage) errors[property].push(errorMessage)
}
return errors
}, {})
}
// --- helper function (returns error messages) ---
function validateLengthMessage(value, length) {
if (value == null) return
if (value.length >= length) return
return `must be ${length} or more characters`
}
function validateRequiredMessage(value) {
if (value) return
return 'is required'
}
// ---------------------------------------------------
// 2๏ธโฃ
function printErrors(errors) {
Object.entries(errors).forEach(([property, messages]) => {
messages.forEach(message => {
console.error(`${property} ${message}`)
})
})
}
module.exports = {
validationMessages,
printErrors
}
// main.js
const { updateUser, createUser } = require('./api/users')
const { validationMessages, printErrors } = require('./pro/validation')
function saveUser(user) {
if (user.id == null) {
console.log('Created User')
createUser(user)
} else {
console.log('Updated User')
updateUser(user)
}
}
function validateUser(user) {
// hash of validations
const validations = {
username: {
required: true,
length: 3
},
password: {
required: true,
length: 8
}
}
const errors = validationMessages(validations, user)
return {
valid: Object.values(errors).every(messages => messages.length === 0),
errors: errors
}
}
const user = {
id: 1,
username: 'USER',
password: 'password'
}
const { errors, valid } = validateUser(user)
if (valid) {
saveUser(user)
} else {
printErrors(errors)
}