본 게시글은 책 클린코드와 클린코드 for 타입스크립트 을 정리한 내용입니다
if / else 문 , while 문
등에 들어가는 블록은 한 줄 이어야 한다.function parseCode(code: string) {
const REGEXES = [
/* ... */
]
const statements = code.split(' ')
const tokens = []
REGEXES.forEach(regex => {
statements.forEach(statement => {
// ...
})
})
const ast = []
tokens.forEach(token => {
// lex...
})
ast.forEach(node => {
// parse...
})
}
const REGEXES = [
/* ... */
]
function parseCode(code: string) {
const tokens = tokenize(code)
const syntaxTree = parse(tokens)
syntaxTree.forEach(node => {
// parse...
})
}
function tokenize(code: string): Token[] {
const statements = code.split(' ')
const tokens: Token[] = []
REGEXES.forEach(regex => {
statements.forEach(statement => {
tokens.push(/* ... */)
})
})
return tokens
}
function parse(tokens: Token[]): SyntaxTree {
const syntaxTree: SyntaxTree[] = []
tokens.forEach(token => {
syntaxTree.push(/* ... */)
})
return syntaxTree
}
if (subscription.isTrial || account.balance > 0) {
// ...
}
function canActivateService(subscription: Subscription, account: Account) {
return subscription.isTrial || account.balance > 0
}
if (canActivateService(subscription, account)) {
// ...
}
function isEmailNotUsed(email: string): boolean {
// ...
}
if (isEmailNotUsed(email)) {
// ...
}
function isEmailUsed(email): boolean {
// ...
}
if (!isEmailUsed(node)) {
// ...
}
if 블록
혹은 switch case
가 1가지 이상이 있다면 해당 함수는 1개 이상의 일을 하고 있는 것이다.class Airplane {
private type: string
// ...
getCruisingAltitude() {
switch (this.type) {
case '777':
return this.getMaxAltitude() - this.getPassengerCount()
case 'Air Force One':
return this.getMaxAltitude()
case 'Cessna':
return this.getMaxAltitude() - this.getFuelExpenditure()
default:
throw new Error('Unknown airplane type.')
}
}
private getMaxAltitude(): number {
// ...
}
}
abstract class Airplane {
protected getMaxAltitude(): number {
// shared logic with subclasses ...
}
// ...
}
class Boeing777 extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount()
}
}
class AirForceOne extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude()
}
}
class Cessna extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getFuelExpenditure()
}
}
인수는 2개 이하가 적당하다.
인수가 3개 이상이 될 경우, 테스트 할 때 3개의 다른 인수를 넣어줘야하므로 매우 복잡해지고, 해당 함수 호출 시 함수가 어떤 일을 하는지 명확히 판단하기 어렵다.
여러개의 인수를 사용해야한다면, 객체 리터럴을 사용하도록 한다.
객체 리터럴을 사용 할 때 구조분해 구문을 사용하면 아래와 같은 이점이 있다.
함수 인수로 플래그(flag) 사용하지 않기
function set(attribute: String, value: String){
//....
};
if(set("username","bob")) ...
if (attributeExist('username')) {
setAttribute('username', 'bob')
}
type MenuConfig = {
title?: string
body?: string
buttonText?: string
cancellable?: boolean
}
function createMenu(config: MenuConfig) {
config.title = config.title || 'Foo'
config.body = config.body || 'Bar'
config.buttonText = config.buttonText || 'Baz'
config.cancellable =
config.cancellable !== undefined ? config.cancellable : true
// ...
}
createMenu({ body: 'Bar' })
type MenuConfig = {
title?: string
body?: string
buttonText?: string
cancellable?: boolean
}
function createMenu(config: MenuConfig) {
const menuConfig = Object.assign(
{
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true,
},
config
)
// ...
}
createMenu({ body: 'Bar' })
function createMenu({
title = 'Foo',
body = 'Bar',
buttonText = 'Baz',
cancellable = true,
}: MenuConfig) {
// ...
}
createMenu({ body: 'Bar' })
값을 가져와서 → 다른 값을 반환
하는 로직을 지켜야한다.let name = 'Robert C. Martin'
function toBase64() {
name = btoa(name)
}
toBase64()
console.log(name)
// 'Robert C. Martin'이 출력되는 것을 예상했지만
// 'Um9iZXJ0IEMuIE1hcnRpbg=='가 출력됨
const name = 'Robert C. Martin'
function toBase64(text: string): string {
return btoa(text)
}
const encodedName = toBase64(name)
console.log(name)