Open j03y14 opened 5 months ago
상속을 남용하는 상태를 살펴보고, 객체 작성 이라는 형식으로 실행 중에 클래스를 꾸미는 방법을 배웁니다.
기존 클래스를 고치지 않고도 객체에 새로운 역할을 추가할 수 있습니다.
음료 제작 클래스
커피 주문에 따라 들어가는 재료의 경우의 수가 모두 개별적으로 생성해야한다.
재료의 가격이 인상되거나, 새로운 재료가 추가된다면?
지켜지지 않은 디자인 원칙은 아마 2, 4 인듯?
이를 해결하기 위해 각 첨가물에 해당하는 boolean 변수를 추가하고
각 메뉴마다 서브클래스를 만든다.
public class Beverage {
public double cost() {
double condiment = 0.0;
if(hasMilk()) {
condiment += milkCost;
}
if(hasSoy()) {
condimentCost += soyCost;
}
// ...
}
}
public class DarkRoast extends Beverage {
public DarkRoast() {
description = 'the best dark roast coffee';
}
public double cost() {
return 1.99 + super.cost();
}
}
첨가물의 가격이 바뀌거나 첨가물의 종류가 많아지면 코드를 수정해야한다.
불필요한 메서드를 항상 상속받는 클래스가 존재한다.
첨가물이 두번 들어간 음료가 있다면?
상속이 강력하긴 하나 구성으로 객체를 확장하면 실행 중에 행동을 상속할 수 있다
디자인 원칙 클래스는 확장에는 열려있어야 하지만 변경에는 닫혀있어야 한다.
상속을 써서 음료 가격과 첨가물 가격을 합해서 총 가격을 산출하는 방법은 그리 좋은 방법이 아니었다. 일단 특정 음료에서 시작해서 첨가물로 그 음료를 장식하는 방법을 생각해보자
데코레이터 패턴으로 객체에 추가요소를 동적으로 더할 수 있습니다. 데코레이터를 사용하면 서브클래스를 만들 때 보다 훨씬 유연하게 기능을 확장할 수 있습니다.
팩토리나 빌더같은 다른 패턴으로 만들고 사용하게 된다.
스타버즈
클래스가 너무 많아지는 문제가 발생.
두가지 디자인 원칙을 지키지 않고 있음.
첨가물을 super class에서 관리하면 되지 않나?
이 코드의 문제점
상속을 받으면 행동이 컴파일 할 때 완전히 결정된다. 대신 구성을 사용하면 동적으로 행동을 설정할 수 있다. 구성을 사용하면 기존 코드를 고치는 대신 확장할 수 있다.
코드를 확장해야할 부분을 선택할 때는 세심한 주의가 필요하다. 무조건 OCP를 적용하면 괜히 쓸데없는 일을 하며 시간 낭비를 할 수 있다.
데코레이터 패턴
특정 음료에서 시작해서 음료를 장식해보자(데코레이터 패턴)
이를 가능하게 하기 위해서,
데코레이터 패턴의 정의
객체에 추가적인 요소를 동적으로 더해서 유연하게 기능을 확장할 수 있도록 하는 패턴
데코레이터 패턴으로 코드 수정
데코레이터 패턴의 한계점?