자바의 입출력 스트림은 데코레이터 패턴을 사용

실제 입출력 기능을 가진 객체(컴포넌트)와 그 외 다양한 기능을 제공하는 데코레이터(보조스트림)을 사용하여 다양한 

입출력 기능 구현

 

상속보다 유여한 확장성을 가짐

지속적인 서비스의 증가와 제거가 용이함 

 

*언리얼엔진 Component들과 유사합니다.

 언리얼 엔진에서도 Actor나 Object 클래스에 Component 클래스의 기능을 붙여서 확장하는 개념입니다.

Component또한 보조 스트림과 같은 혼자서는 기능은 못하지만 스트림과 같이 독립적으로 존재하는 클래스에 기능을 확장해주는 역할을합니다. 

 

데코레이터 패턴 

출처:minsone.github.io/programming/designpattern-decorator

 

[DesignPattern]데코레이터 패턴(Decorator Pattern)

데코레이터 패턴(Decorator Pattern) 데코레이터 패턴은 기존의 코드를 건드리지 않고 확장하도록 합니다. 디자인의 원칙 중 하나인 OCP(Open-Closed Principle)을 준수합니다. 출처 : Head First Design Pattern Compo

minsone.github.io

위의 그림을 보면 조금 어려워 보일수도 있습니다.

쉬운 예제로 데코레이터의 차트를 그려보겠습니다.

아래 코드 커피머신 제조기 패턴인데 먼저 클래스 차트를 그려보겠습니다.

 

여기서 보는 클래스를 보면  Coffee와 DecrateCoffee는 추상 클래스에 속성을 가집니다.

오직 이 커피라는 베이스로 들어가는 Americano만 혼자 구체화가 가능합니다. 즉 Milk나 Moca도 DecrateCoffee에게 상속받았지만 혼자 사용하는게 불가능합니다(보조 스트림 유사)

지난번에 배운 입출력 클래스와 비슷합니다.

 

그렇다면 이해를 위해서 한번코드를 확인해보겠습니다.

 

ex) 커피머신 데코레이터 패턴을 만들어보겠습니다.

아메리카노 

라떼=아메리카노 +우유

모카=아메리카노 +우유+모카시럽

 

먼저 추상클래스인 

Coffee:

package Test01;

public abstract class Coffee {

	
	public abstract void brewing();
	
}

여기서 brewing();은 추상 메서드로 파생 클래스에 어떤 재료가 추가되는지에 따른 커피종류가 달라집니다.

Americano:

package Test01;

public class Amaricano extends Coffee {

	@Override
	public void brewing() {
		System.out.print("Amaricano");
		
	}
}

 아메리카노는 가장 모든 커피에 들어가는 베이스 클래스이며 또한 아메리카노라는 메뉴가 존재하기 때문에 혼자서도 구체화가 가능해야합니다. 

Decorate:

package Test01;

public abstract class DecorateCoffee extends Coffee {

	Coffee coffee;
	public DecorateCoffee(Coffee coffee) {
		this.coffee=coffee;
	}
	
	@Override
	public void brewing() {
		// TODO Auto-generated method stub
		coffee.brewing();
	}
}

무슨 Coffee를 만들어줄지 즉 Americano의 기능을 확장하기 위해서 Americano 부모 클래스인 Coffee를 상속받아

생성자에서 Coffee로 받아서 먼저 들어갈 재료coffee.brewing(); 출력해줍니다.

Milk:

package Test01;

public class Milk extends DecorateCoffee{
	public Milk(Coffee coffee) {
		super(coffee);
		// TODO Auto-generated constructor stub
	}
	@Override
	public void brewing() {
		// TODO Auto-generated method stub
		super.brewing();
		System.out.print(" Add Milk");
	}

}

Milk는 라떼를 만들어주는 클래스입니다. 

당연히 라떼는 아메리카노 + 우유 라는 재료 가 들어갑니다. 

그렇다면 먼저 아메리카노 super 클래스에서 불러준다음에 

Add Milk를 하면 American Add Milk가 호출될겁니다.

Moca:

package Test01;

public class Moca extends DecorateCoffee{

	public Moca(Coffee coffee) {
		super(coffee);
		// TODO Auto-generated constructor stub
	}
	@Override
	public void brewing() {
		// TODO Auto-generated method stub
		super.brewing();
		System.out.print(" Add Moca");
	}
}

Moca도 마찬가지로   American Add Milk Add Moca가 들어가야 하기 떄문에 이전에 Milk가 보조 스트림처럼 붙은 상태에서 Moca를 추가해줍니다.

 

Main:

package Test01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.net.Socket;



public class Main {

	
	
	public static void main(String [] args) throws IOException   {
		
		Coffee amricano=new Amaricano();
		
		amricano.brewing();
		System.out.println();
		//점점 기능을 늘려감 
		
		Coffee latte=new Milk(new Amaricano());//decorate 
		latte.brewing();
		
		System.out.println();
		Coffee moca=new Moca(new Milk(new Amaricano()));//decorate 
		moca.brewing();
	}
	
	
	
}

최종 적으로 사용방법으 메인을 보면 

아메리카노 출력문:

Coffee amricano=new Amaricano();
		
		amricano.brewing();
		System.out.println();

라떼 출력문:

Coffee latte=new Milk(new Amaricano());//decorate 
		latte.brewing();
		

모카 출력문:

Coffee moca=new Moca(new Milk(new Amaricano()));//decorate 
		moca.brewing();

이전에 배운 스트림 + 보조 스트림 +보조 스트림 + .....

점점 기능을 늘려나가는 상황을 데커레이션 패턴 이라고 합니다. 

결과: 

'프로그래밍언어 > JAVA' 카테고리의 다른 글

<JAVA>멀티스래드 프로그래밍-1  (0) 2020.12.13
<JAVA>Thread  (0) 2020.12.13
<JAVA>몇가지 추가 입출력 클래스  (0) 2020.12.13
<JAVA>직렬화  (0) 2020.12.13
<JAVA>보조 스트림  (0) 2020.12.12

+ Recent posts