SELF STUDY/Design Pattern

[디자인패턴] 데코레이터 패턴 | Decorator pattern

호이호이호잇 2021. 9. 1. 19:26
728x90
반응형

오늘 공부해 볼 패턴은 데코레이터 패턴!

 


데코레이터 패턴 이란?

데코레이터 패턴(Decorator pattern)이란 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다. (출처 : 위키백과)


정의는 위와 같습니다.

제가 이해한 것을 바탕으로 데코레이터 패턴을 재정의 한다면, 기본 틀을 바탕으로 그 위에 을 추가하여 점점 커지게 만드는 패턴 이라고 할 수 있을 것 같습니다.

 

예를 들어 설명해보겠습니다.

 

샌드위치 집에 방문했다고 생각을 합시다.

메뉴에서 샌드위치를 고르게 됩니다. 기본 샌드위치, 햄치즈 샌드위치 등등..

그 뒤에 무엇을 결정하죠?

바로바로~ 토핑을 추가할지 말지 결정하게 됩니다.

위 사진처럼 기본 샌드위치에 베이컨, 아보카도, 에그 와 같은 다양한 토핑을 추가 할 수 있습니다.

이러한 토핑을 저는 데코레이터 패턴으로 적용해보았는데요.

 

- Sandwich.java

샌드위치의 기본 틀이 되는 Sandwich 소스 입니다.

public abstract String make() : 만들어진 샌드위치토핑의 이름을 반환합니다. ex) 기본 베이컨

package com.codingstorywithme.designpattern.deco;

public abstract  class Sandwich {

    public abstract String make();
    public abstract int cost();
}

 

- DecoActivity.java

위에서 말한 샌드위치의 토핑을 표현한 소스가 있는 activity 파일 입니다.

편의를 위해 한 파일에 여러 class를 정의하였는데, 단락을 나누어 설명해드리겠습니다.

 

 

1. DecoActivity

토핑을 추가한 샌드위치를 고르고, 그것을 화면에 보여주는 class입니다.

package com.codingstorywithme.designpattern.deco;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DecoActivity extends AppCompatActivity implements View.OnClickListener {

    BasicSandwich mBasicSandwich;

    TextView costTextView;
    TextView menuTextView;

    Button avoButton;
    Button baconButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_deco);

        initUI();

        mBasicSandwich = new BasicSandwich();
        costTextView.setText(""+mBasicSandwich.cost());
        menuTextView.setText(mBasicSandwich.make());

    }

    private void initUI(){
        costTextView = findViewById(R.id.cost);
        menuTextView = findViewById(R.id.menu);

        avoButton = findViewById(R.id.avoButton);
        avoButton.setOnClickListener(this);
        baconButton = findViewById(R.id.baconButton);
        baconButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.avoButton:
                AvoSandwich avoSandwich = new AvoSandwich(mBasicSandwich);
                costTextView.setText(""+avoSandwich.cost());
                menuTextView.setText(avoSandwich.make());
                break;
            case R.id.baconButton:
                BaconSandwich baconSandwich = new BaconSandwich(mBasicSandwich);
                costTextView.setText(""+baconSandwich.cost());
                menuTextView.setText(baconSandwich.make());
                break;
        }
    }
}

 

2. BasicSandwich

기본틀 위에 기본 샌드위치를 표현하였습니다.

class BasicSandwich extends Sandwich{

    private static final int basicCost = 50;
    private static final String basicName = "Basic";

    @Override
    public String make() {
        return basicName;
    }

    @Override
    public int cost() {
        return basicCost;
    }
}

 

3. SandwichDecorator

샌드위치에 토핑을 얹을 수 있도록 해주는 데코레이터 class 입니다.

abstract class SandwichDecorator extends Sandwich{

    private Sandwich sandwich;

    public SandwichDecorator(Sandwich sandwich){
        this.sandwich = sandwich;
    }

    @Override
    public String make() {
        return sandwich.make();
    }

    @Override
    public int cost() {
        return sandwich.cost();
    }
}

 

4. AvoSandwich

아보카도 토핑을 추가한 샌드위치 class 입니다.

class AvoSandwich extends SandwichDecorator{

    private static final int avoCost = 20;
    private static final String avoName = " Avo";

    public AvoSandwich(Sandwich sandwich) {
        super(sandwich);
    }

    @Override
    public String make(){
        return super.make() + avoName;
    }

    @Override
    public int cost() {
        return super.cost() + avoCost ;
    }
}

 

5. BaconSandwich

베이컨 토핑을 추가한 샌드위치 class 입니다.

class BaconSandwich extends SandwichDecorator{

    private static final int baconCost = 10;
    private static final String baconName = " Bacon";

    public BaconSandwich(Sandwich sandwich) {
        super(sandwich);
    }

    @Override
    public String make(){
        return super.make() + baconName;
    }

    @Override
    public int cost() {
        return super.cost() + baconCost ;
    }
}

 

- 샘플앱 동작

화면 입니다.

동작 영상

 

 

추가로 안드로이드 소스에서 데코레이터 패턴으로 보이는? 부분도 캡처해보았습니다.

 

android/frameworks/base/core/java/android/view/InputEvent.java

 

android/frameworks/base/core/java/android/view/KeyEvent.java

...

728x90
반응형