3. Functions
이 게시물은 Rober C. Martin의 책 Clean Code 를 자바스크립트에 맞게 조정한 Ryan McDermott의 깃허브 리포지토리를 직접 타이핑함으로써 학습의 목적으로 작성하게 되었으며 3. Functions 의 부분에 해당합니다.
1. 함수 인자는 2개 이하가 이상적이다.
함수의 인자, 매개변수가 많아진다는 것은 그 함수에게 너무 많은 역활을 부여하고 있는 것이 아닌지 생각해 보아야 한다.
함수는 인자를 1 ~ 2 개 가지고 있는것이 가장 이상적이며 만일 3개 이상의 인자를 가져야 한다면 그러한 인자들로 구성된 하나의 객체를 함수의 인자로 넘겨주자.
함수 내부에서는 넘겨받은 객체를 ES2015/ES6 의 구조분해할당
을 통해 개별 변수에 값을 할당하여 사용할 수 있다.
이 구문은 여러가지의 장점이 존재한다.
- 그 함수를 보게 될 때 어떤 속성들이 사용되는지 한눈에 알 수 있다.
구조분해할당
은 함수에 전달되는 객체의 기본속성을 복제하여사이드이펙트
가 일어나는 것을 방지한다.
BAD 😑
function createMenu(title, body, buttonTest, cancellable) {
// ...
}
GOOD 😊
function createMenu({ title, body, buttonText, cancellable }) {
// ...
}
createMenu({
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true,
});
2. 함수는 하나의 행동만 해야한다.
함수가 1개 이상의 행동을 하게 된다면 작성, 테스트, 이해 부분에서 모두 어려워진다. 만일 하나의 함수에 하나의 역활만을 부여한다면 좀 더 고치기 쉽고 이해하기 쉬울 것이다.
BAD 😑
function emailClients(clients) {
clients.forEach((client) => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
GOOD 😊
function emailClients(clients) {
clients.filter(isClientActive).forEach(email);
}
function isClientActive(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
3. 함수명은 함수가 무엇을 하는지 알 수 있어야 한다.
BAD 😑
function AddToDate(date, month) {
// ...
}
GOOD 😊
function AddMonthToDate(date, month) {
// ...
}
4. 함수는 단일 행동을 추상화 해야한다.
BAD 😑
function parseBetterJSAlternative(code) {
const REGEXES = [
// ...
];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
// ...
});
});
const ast = [];
tokens.forEach((token) => {
// ...
});
ast.forEach((node) => {
// parse...
});
}
GOOD 😊
function tokenize(code) {
const REGEXES = [
// ...
];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
tokens.push(/* ... */);
});
});
return tokens;
}
function lexer(tokens) {
const ast = [];
tokens.forEach((token) => {
ast.push(/* ... */);
});
return ast;
}
function parseBetterJSAlternative(code) {
const tokens = tokenize(code);
const ast = lexer(tokens);
ast.forEach((node) => {
// parse...
});
}
5. 중복된 코드는 작성을 지양한다.
BAD 😑
function showDeveloperList(developers) {
developers.forEach((developers) => {
const expectedSalary = developer.calculateExpectedSalary();
const experience = developer.getExperience();
const githubLink = developer.getGithubLink();
const data = {
expectedSalary,
experience,
githubLink,
};
render(data);
});
}
function showManagerList(managers) {
managers.forEach((manager) => {
const expectedSalary = manager.calculateExpectedSalary();
const experience = manager.getExperience();
const portfolio = manager.getMBAProjects();
const data = {
expectedSalary,
experience,
portfolio,
};
render(data);
});
}
GOOD 😊
function showEmployeeList(employees) {
employees.forEach((employee) => {
const expectedSalary = employee.caculateExpectedSalary();
const experience = employee.getExperience();
let portfolio = employee.getGithubLink();
if (employee.type === "manager") {
portfolio = employee.getMBAProjects();
}
const data = {
expectedSalary,
experience,
protfolio,
};
render(data);
});
}
6. Object.assign을 사용하여 기본이 되는 객체를 만든다.
기본이 되는 Object를 생성하여 추가적으로 assign을 통해 targetObject를 덮어씌우는 방식으로 진행하라고 이해하였다.
BAD 😑
const menuConfig = {
title: null,
body: "Bar",
buttonText: null,
cancellable: true,
};
function createMenu(config) {
config.title = config.title || "Foo";
config.body = config.body || "Bar";
config.buttonText = config.buttonText || "Baz";
config.cancellable =
config.cancellable !== undefined ? config.cancellable : true;
}
createMenu(menuConfig);
GOOD 😊
const menuConfig = {
title: "Order",
// 유저가 'body' key의 value를 정하지 않았다.
buttonText: "Send",
cancellable: true,
};
function createMenu(config) {
config = Object.assign(
//target Object
{
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true,
},
config
);
/*
config = {
title: "Order",
body: "Bar",
buttontext: "Send",
cancellable: true}
*/
}
createMenu(menuConfig);
7. 매개변수로 플래그를 사용하지 않는다.
플래그 변수: boolean(true, false)값을 가지는 변수
플래그를 사용한다는 것은 해당 함수가 한가지 이상의 역활을 하고 있다는 것을 뜻한다. 만일 플래그에 의해 나눠지는 코드가 존재한다면 별도의 함수로 분리하자.
BAD 😑
function createFile(name, temp) {
if (temp) {
fs.create("./temp/${name}");
} else {
fs.create(name);
}
}
GOOD 😊
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`);
}
출처
clean-code-javascript / Ryan McDermott [https://github.com/ryanmcdermott/clean-code-javascript]
'JavaScript' 카테고리의 다른 글
[JavaScript] Map, Set 살펴보기 (0) | 2022.04.23 |
---|---|
[JavaScript] 최신문법 정리 (0) | 2022.01.21 |
[JavaScript] 변수(Variable) (0) | 2021.11.14 |
[JavaSCript] 자바스크립트 기본 내장객체 (Object, Number, Stirng, Date, Math, JSON ) (0) | 2021.11.14 |
[JavaScript] DOM(Document Object Model) (0) | 2021.11.10 |