인스턴스 변수를 안전하게 조작하도록 메서드를 설계하면, 클래스 내부가 정상적인 상태인지 보장할 수 있다.
다른 클래스의 인스턴수 변수를 변경하는 메서드는 좋지 않다. 다른 클래스의 인스턴스 변수를 변경하는 메서드를 작성할 때는 변경된 내용을 다루는 새로운 인스턴스를 생성하고 이를 리턴하는 것이 좋다.(불변성과 관련있는 듯)
가변 인스턴스 변수 등을 변경하는 메서드는 의도하지 않게 다른 부분에 영향을 줄 수 있다.
불변을 활용해서 예상치 못한 동작 자체를 막을 수 있게 설계하자
equipArmor 메서드처럼 ‘다른 클래스를 확인하고 조작하는 메서드 구조’는 응집도가 낮은 구조이다.
class Person {
private name: string;
getName(): string {
return name;
}
setName(newName: string): void {
this.name = newName;
}
}
getter/setter는 ‘다른 클래스를 확인하고 조작하는 메서드 구조’가 되기 쉽다.
Equipment 클래스처럼 호출되는 메서드 쪽에서 처리를 하는 형태로 만드는 것이다.
이 메소드는 상태 변경과 추출을 동시에 진행하고 있다.
gainAndGetPoint(): number {
this.point += 10;
return point;
}
메서드는 커맨드 또는 쿼리 중에 하나만 하도록 설계해야 한다는 패턴이 커멘드/쿼리 분리(CQS, Command-Query Seperation)이다.
메서드 종류 구분 | 설명 |
---|---|
커맨드 | 상태를 변경하는 것 |
쿼리 | 상태를 리턴하는 것 |
모디파이어 | 커멘드와 쿼리를 동시에 하는 것 |
커맨드와 쿼리로 분리해 코드를 단순화 시키자
gainPoint(): void {
this.point += 10;
}
getPoint(): number {
return point;
}
class Price {
add(other: Price): number {
return this.amount + other.amount;
}
}
단순한 기본 자료형으로는 리턴값의 의미를 호출하는 쪽에 전달할 수 없다.
let price = productPrice.add(otherPrice);
let discountedPrice = calcDiscountedPrice(price);
let deliveryPrice = calcDeliveryPrice(discountedPrice);
모든 자료형이 number
면 매개변수를 잘못 전달하는 등의 실수가 발생할 수 있다.
// DeliveryCharge에는 배송비가 전달되어야 하는데
// 상품 가격 합계가 전달디고 있다.
const deliveryChage = new DeliveryCharge(price);
add메서드의 리턴형을 Price 자료형으로 변경해 의도를 명확히 한다.
class Price {
add(other: Price): Price {
const added = this.amount + other.amount;
return new Price(added);
}
}
매개변수로 null을 전달하지 않는 것이 좋듯이 ,null을 리턴하지 않아야 좋다.
// Bad
class Location {
shift(shiftX: number, shiftY: number) {
let nextX = x + shiftX;
let nextY = y + shiftY;
if (this.valid(nextX, nextY)) {
return new Location(nextX, nextY);
}
return new Location(-1, -1);
}
}
// Good
class Location {
constructor(x: number, y: number) {
if (!this.valid(x, y)) {
throw new Error("잘못된 위치입니다.");
}
this.x = x;
this.y = y;
}
shift(shiftX: number, shiftY: number) {
let nextX = x + shiftX;
let nextY = y + shiftY;
return new Location(nextX, nextY);
}
}
‘오류가 있을 때, 오류 값으로 Location(-1, -1)을 리턴한다’ 라는 사실을 알고 있어야 하며, 해당 값을 후속 로직에서 정상 값처럼 사용되어 버그가 생길 것이다. 코드가 중의적으로 해석할 만한 것은 피해야 한다.
리턴 값으로 오류 값을 리턴하지 말고 바로 예외를 발생 시키자