
자바스크립트에서는 객체 지향 프로그래밍에서 중요한 개념인 캡슐화를 클로저를 이용해 구현할 수 있습니다. 이번 글에서는 캡슐화의 개념과 이를 적용하는 방법을 알아보겠습니다.
이전에는 다음과 같은 코드로 캡슐화를 배웠습니다:
class User {
constructor(email, birthdate) {
this.email = email;
this.birthdate = birthdate;
}
buy(item) {
console.log(`${this.email} buys ${item.name}`);
}
get email() {
return this._email;
}
set email(address) {
if (address.includes('@')) {
this._email = address;
} else {
throw new Error('invalid email address');
}
}
}
const user1 = new User('chris123@google.com', '1992-03-21');
user1.email = 'newChris123@google.com';
console.log(user1.email);
이 코드에서 _email 프로퍼티를 직접 접근하지 않고, email이라는 getter/setter 메소드로 접근하도록 하였습니다. 하지만 _email 프로퍼티에 직접 접근할 수 있기 때문에 완벽한 캡슐화가 되지 않았습니다:
console.log(user1._email);
user1._email = 'chris robert';
자바스크립트에는 private 키워드가 없기 때문에 클로저(closure)를 이용해 완벽한 캡슐화를 할 수 있습니다. 아래는 클로저를 사용한 예시입니다:
function createUser(email, birthdate) {
let _email = email;
const user = {
birthdate,
get email() {
return _email;
},
set email(address) {
if (address.includes('@')) {
_email = address;
} else {
throw new Error('invalid email address');
}
},
};
return user;
}
const user1 = createUser('chris123@google.com', '19920321');
console.log(user1.email); // 'chris123@google.com'
console.log(user1._email); // undefined
클로저를 이용하면 _email 변수에 직접 접근할 수 없으며, getter와 setter를 통해서만 접근할 수 있습니다.
캡슐화는 프로퍼티뿐만 아니라 메소드에도 적용할 수 있습니다. 다음은 메소드를 캡슐화한 예시입니다:
function createUser(email, birthdate) {
let _email = email;
let _point = 0;
function increasePoint() {
_point += 1;
}
const user = {
birthdate,
get email() {
return _email;
},
get point() {
return _point;
},
buy(item) {
console.log(`${this.email} buys ${item.name}`);
increasePoint();
},
};
return user;
}
const item = {
name: '스웨터',
price: 30000,
};
const user1 = createUser('chris123@google.com', '19920321');
user1.buy(item);
user1.buy(item);
user1.buy(item);
console.log(user1.point); // 3
user1.increasePoint(); // 에러: user1.increasePoint is not a function
위 코드에서 increasePoint 함수는 클로저로 캡슐화되어 user1 객체에서는 직접 접근할 수 없습니다. buy 메소드에서만 호출이 가능합니다.
자바스크립트에서는 클로저를 사용하여 프로퍼티와 메소드를 완벽하게 캡슐화할 수 있습니다. 캡슐화를 통해 객체의 내부 상태를 보호하고, 외부에서 직접 접근할 수 없도록 할 수 있습니다. 이는 객체 지향 프로그래밍의 중요한 개념으로, 코드의 안정성과 유지보수성을 높이는 데 큰 도움이 됩니다.
이번 글에서는 자바스크립트에서 객체를 캡슐화하는 방법에 대해 알아보겠습니다. 특히 BankAccount 클래스를 예시로 들어서 프로퍼티와 메소드를 안전하게 보호하는 방법을 살펴보겠습니다.
현재 BankAccount 클래스는 _balance라는 프로퍼티를 통해 계좌의 잔액을 관리합니다. 이 프로퍼티에 직접 접근해서 값을 수정하는 것은 매우 위험하기 때문에, 이를 캡슐화하려고 합니다.
이미 balance라는 getter 함수는 정의되어 있으며, 이제 balance라는 setter 함수도 정의해 보겠습니다. 이 setter 함수는 다음과 같은 기능을 합니다:
1. 파라미터로 전달된 금액이 0 이상일 때만 _balance 프로퍼티의 값으로 설정한다.
2. 음수일 때 'You cannot set negative number for balance'라는 문장을 출력한다.
먼저, BankAccount 클래스에 setter 메소드를 추가하여 캡슐화를 구현해보겠습니다.
class BankAccount {
constructor(name, money) {
this.holder = name;
this._balance = money;
}
get balance() {
return this._balance;
}
set balance(money) {
if (money >= 0) {
this._balance = money;
} else {
console.log('You cannot set negative number for balance');
}
}
deposit(money) {
this.balance += money;
}
withdraw(money) {
if (this.balance - money < 0) {
console.log('Insufficient balance');
} else {
this.balance -= money;
}
}
transfer(money, anotherAccount) {
const account = anotherAccount;
if (this.balance - money < 0) {
console.log('Insufficient balance');
} else {
this.balance -= money;
account.balance += money;
}
}
}
const account1 = new BankAccount('Michael', 10000);
account1.balance = 20000;
account1.balance = -5000;
이렇게 하면 _balance 프로퍼티에 직접 접근하지 못하고, setter 메소드를 통해서만 접근할 수 있게 됩니다.
위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다:
You cannot set negative number for balance
이제 _balance에 직접 접근하는 것을 막기 위해 클로저를 이용해 완벽한 캡슐화를 구현해 보겠습니다.
클로저를 사용하면 _balance 변수를 외부에서 직접 접근하지 못하도록 완벽하게 보호할 수 있습니다. 이를 위해 createBankAccount라는 팩토리 함수를 사용합니다.
function createBankAccount(name, money) {
const holder = name;
let _balance = money;
const account = {
get balance() {
return _balance;
},
set balance(money) {
if (money >= 0) {
_balance = money;
} else {
console.log('You cannot set negative number for balance');
}
},
deposit(money) {
this.balance += money;
},
withdraw(money) {
if (this.balance - money < 0) {
console.log('Insufficient balance');
} else {
this.balance -= money;
}
},
transfer(money, anotherAccount) {
const account = anotherAccount;
if (this.balance - money < 0) {
console.log('Insufficient balance');
} else {
this.balance -= money;
account.balance += money;
}
},
};
return account;
}
const account1 = createBankAccount('Michael', 10000);
console.log(account1._balance); // undefined 출력
account1.balance = 20000;
account1.balance = -5000; // 'You cannot set negative number for balance' 출력
자바스크립트에서는 클로저를 사용하여 프로퍼티와 메소드를 완벽하게 캡슐화할 수 있습니다. 이렇게 하면 객체의 내부 상태를 외부에서 직접 접근할 수 없게 보호할 수 있으며, 이는 보다 안정적이고 유지보수하기 쉬운 코드를 작성하는 데 큰 도움이 됩니다. 캡슐화는 객체 지향 프로그래밍의 중요한 개념으로, 이를 이해하고 적절히 활용하는 것이 중요합니다.