본문 바로가기

디자인 패턴/디자인 패턴

[디자인 패턴] 데코레이터 패턴 문제 - 노트북

책을 공부하며 새로운 문제를 만들고 구현한것을 기록한 게시글입니다.

(이해한 내용을 바탕으로 작성했기 때문에, 내용이 정확하지않고 틀린부분이 있을수있으며, 예시가 패턴을 사용하기에 알맞지 않을수도있습니다)


 

데코레이터 패턴

- 객체에 추가 구성요소를 동적으로 더할 수 있는 패턴.

(데코레이터를 사용하면, 유연하게 객체에 추가 구성요소를 넣을수있다.)


문제

노트북이 고장난 명진이는 노트북을 구매하기로 결심했다.

 

노트북의 종류는 3가지가 있으며, 각 노트북의 이름과 가격은 다음과같다.

 

Mac - $1500

Gram - $1200

surf - $1100

 

노트북을 구매할때 부가옵션을 추가할수있으며, 부가옵션은 다음과 같다.

 

Mac

- Memory256GB $250

- Memory512GB $450

- Memory1TB $ 900

- Corei5 $250

 

Gram, Surf

- Memory256GB $100

- Memory512GB $150

- Memory1TB $250

- Corei5 $200

 

명진이가 살 노트북과 선택한 부가옵션이 주어질때, 최종가격과 노트북의 종류, 부가옵션을 출력하자.

 

입력은 다음과 같다.

노트북종류 부가옵션의 갯수 부가옵션, 부가옵션, 부가옵션 ...

 

입력 : Mac 2 Memory1TB Corei5

출력 : $2650 Mac, 1TBMemory, Core-i5


구현

노트북을 표현하는 인터페이스 notebook을 만들었다. 인터페이스 코드는 다음과 같다.

 
package notebook.Super;

public interface notebook {
    boolean getOS();
    int getPrice();
    String getOptions();
}

 

 

노트북 클래스, Mac, Gram, Surf를 만들고 notebook인터페이스를 구현했다.

(구현하고 든 생각인데, notebook인터페이스를 추상클래스로 만들고 바뀌는것은 오버라이딩해서 구현했으면 여러번 구현해야하는 메소드를 줄일수있어서 더 편했을것 같다.)

노트북 클래스중 Mac은 다음과 같다.

package notebook.notebooks;

import notebook.Super.*;

public class Mac implements notebook{
    private String name;
    private int price;
    
    public Mac(){
        this.name = "Mac";
        this.price = 1500;
    }
    
    public boolean getOS(){
        return true;
    }
    
    public int getPrice(){
        return this.price;
    }
    
    public String getOptions(){
        return this.name;
    }
    
}

 

이제 데코레이션 클래스를 만들어야한다.

다형성을 사용하기위해, 데코레이션의 메인클래스mainOption에 notebook을 구현했다.

 

노트북의 옵션 Corei5, Memory1TB, Memory256GB, Memory512GB 들은 mainOption을 확장한다.

 

각 데코레이션들(Corei5, Memory1TB...)은 노트북의 OS종류에 따라 다른cost 값을 반환해야하므로, mainOption의 cost를 Override해서 다시 만든다.

 

Corei5의 소스코드는 다음과같다.

package notebook.options;

import notebook.Super.*;

public class Corei5 extends mainOption{
    
    public Corei5(notebook Notebook){
        this.Notebook = Notebook;
        this.option = ", Core-i5 ";
    }
    
    @Override
    public int getPrice(){
        int ret = 0;
        if(Notebook.getOS()) ret = 250;
        else ret =  200;
        return ret + Notebook.getPrice();
    }
    
}

 

코드를 구현하고 보니, 책의 예제와 너무 비슷한 코드가 나온것같다.. (문제가 비슷했던듯) 

데코레이터 패턴은 여러가지의 객체 A,B,C...에 상태 1,2,3...을 입힐때 유용하게 쓰인다.

- A1,B1,C1,A2,B2,C2와 같은 객체를 따로 만들지않고, 객체와 상태만 만듦으로써 재사용성과, 변화에는 닫히고 확장에는 열린 코드를 만들수있다

 


전체 소스코드

커밋전에 폴더를 정리하고 올리기때문에, 커밋하는 과정에서 경로가 변경되어 코드 실행이 안될수도있다. (모두 실행되는걸 확인하고올리지만) 컴파일시 경로를 변경해서 실행하도록하자.

 

https://github.com/devxb/DesignPatterns/tree/main/DesignPatterns/prob3.notebook

 

devxb/DesignPatterns

디자인 패턴 🤔. Contribute to devxb/DesignPatterns development by creating an account on GitHub.

github.com