Design Pattern : Decorator

0ne·2024년 6월 20일

DesignPattern

목록 보기
5/5

component interface

public interface Beverage {
    String getDescription();
    double cost();
}

concrete component class

  • Component 인터페이스를 구현하며, 기본적인 동작을 정의합니다.
  • 이 클래스는 실제 객체를 나타냄
public class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

decorator abstract class

  • Component 인터페이스를 구현
  • 내부적으로 Component 타입의 객체를 포함
public abstract class BeverageDecorator implements Beverage {
    protected Beverage beverage;

    public BeverageDecorator(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription();
    }
}

concrete decorator class

Decorator 클래스를 확장하여 추가적인 기능을 제공; 이 클래스는 동적으로 기능을 추가할 때 사용

public class Milk extends BeverageDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.50;
    }
}

client에서 활용

  1. 기본 객체 생성: ConcreteComponent 객체를 생성합니다. 이 객체는 기본적인 기능을 가지고 있습니다.

  2. 데코레이터 적용: ConcreteDecoratorA와 ConcreteDecoratorB를 순차적으로 적용하여 기능을 확장합니다. 각 데코레이터는 Component 객체를 인수로 받아 기능을 확장

  3. 재할당(다형적 참조)을 통한 확장된 객체 사용: 확장된 객체를 사용하여 결과를 출력합니다. 각 데코레이터는 이전의 상태를 기반으로 추가 기능을 제공하므로, 결과적으로 객체의 기능이 단계적으로 확장

public class CoffeeShop {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        beverage = new Milk(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        beverage = new Mocha(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
    }
}

[I/O에서의 decorator pattern]

import java.io.*;

public class InputStreamDecoratorExample {
    public static void main(String[] args) {
        String filePath = "example.txt";

        try {
            // FileInputStream을 생성합니다.
            InputStream fileInputStream = new FileInputStream(filePath);

            // FileInputStream을 BufferedInputStream으로 데코레이팅합니다.
            InputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

            // BufferedInputStream을 LineNumberInputStream으로 데코레이팅합니다.
            LineNumberInputStream lineNumberInputStream = new LineNumberInputStream(bufferedInputStream);

            // 파일을 읽고 출력합니다.
            int data;
            while ((data = lineNumberInputStream.read()) != -1) {
                System.out.print((char) data);

                // 줄바꿈 문자일 때 줄 번호를 출력합니다.
                if (data == '\n') {
                    System.out.println("Line number: " + lineNumberInputStream.getLineNumber());
                }
            }

            // 스트림을 닫습니다.
            lineNumberInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
profile
@Hanyang univ(seoul). CSE

0개의 댓글