티스토리 뷰
Decorator Pattern은 기존 객체가 가진 기능에
새로운 기능을 추가하는 방법에 대한 내용입니다.
기존 객체를 수정하지 않고,
좀더 유연하게 새로운 기능을 추가하는 방식을 제공합니다.
새로 추가된 기능들은 손쉽게 조합해서
통일된 방식으로 사용할 수 있습니다.
Decorator Pattern의 가장 대표주자는
Java IO API라고 할 수 있습니다.
InputStream input = new BufferedInputStream( new FileInputStream("text.txt"));
단순하게 파일을 읽는 FileInputStream 객체에
버퍼를 통한 성능향상 기능을 추가할 수 있으며,
그 외에 다양한 기능들을 손쉽게 추가하여 사용할 수 있습니다.
Decorator Pattern을 이용해서
String 변경 Class를 만들어 보도록 하겠습니다.
웹 개발을 하다 보면 보안상의 이유 등으로
입출력된 String을 변경해야 할 경우가 많습니다.
그런 String 변경 기능을 가진 여러개의 Class들을 제작하여
필요 시에 원하는 기능만 조합하여
사용 가능하도록 만들어 보도록 하겠습니다.
우선 String 변경 기능을 가진 Class들이 상속 받고, 구현해야 할
Abstract Class인 SpringTransformer Class을 만듭니다.
* SpringTransformer.java
public abstract class StringTransform { protected StringTransform stringTransform; abstract public String transform(String source); }
이후에 SpringTransformer Class를 상속받는
다양한 기능을 가진 Class를 하나씩 만듭니다.
* RemoveTag.java - <, > 기호를 없애줍니다.
public class RemoveTag extends StringTransform { public RemoveTag() { } public RemoveTag(StringTransform stringTranform) { this.stringTransform = stringTranform; } @Override public String transform(String source) { if(stringTransform != null) { return stringTransform.transform(source).replace("<", "<").replace(">", ">"); } return source.replace("<", "<").replace(">", ">"); } }
* BrToEnter.java - br tag를 엔터키로 변경해 줍니다.
public class BrToEnter extends StringTransform{ public BrToEnter() { } public BrToEnter(StringTransform stringTransform) { this.stringTransform = stringTransform; } @Override public String transform(String source) { if(stringTransform != null) { return stringTransform.transform(source).replace("<br />", "\r\n"); } return source.replace("<br />", "\r\n"); } }
* AddSeperator.java - String ********* 구분자로 감싸줍니다.
public class AddSeperator extends StringTransform { public AddSeperator() {} public AddSeperator(StringTransform stringTransform) { this.stringTransform = stringTransform; } @Override public String transform(String source) { if(stringTransform != null) { return "\r\n***************************************************************\r\n" + stringTransform.transform(source) + "\r\n***************************************************************\r\n"; } return "\r\n***************************************************************\r\n" + source + "\r\n***************************************************************\r\n"; } }
변형 Class들을 사용하는 예시입니다.
* Main.java
public class Main { public static void main(String[] args) { String source = "<h3>Decorator Pattern은 기존 객체에 추가적인 요건을 동적으로 추가할 수 있습니다.</h3>" + "<br /><br /><p>Java IO API가 Decorator Pattern을 사용하고 있습니다.</p>"; StringTransform html = new RemoveTag(new BrToEnter()); StringTransform htmlWithSeperator = new AddSeperator(new RemoveTag(new BrToEnter())); System.out.println(html.transform(source)); System.out.println(htmlWithSeperator.transform(source)); } }
* 출력 결과
<h3>Decorator Pattern은 기존 객체에 추가적인 요건을 동적으로 추가할 수 있습니다.</h3>
<p>Java IO API가 Decorator Pattern을 사용하고 있습니다.</p>
***************************************************************
<h3>Decorator Pattern은 기존 객체에 추가적인 요건을 동적으로 추가할 수 있습니다.</h3>
<p>Java IO API가 Decorator Pattern을 사용하고 있습니다.</p>
***************************************************************
이후 새로운 기능을 가진 Class를 얼마든지 추가해서 사용할 수 있습니다.
참고로, String Class는 수정 불가한 Class이기 때문에
String 객체의 내용을 수정할 때마다 신규로 객체를 생성합니다.
그렇기 때문에 String 객체를 여러번 수정해야 할 경우에는
StringBuilder 등을 사용하는 것이 좋습니다.
Decorator Pattern은 Java IO API에서 볼 수 있듯이
잡다한 Class의 갯수가 많아져서
사용할 때 혼란스러운 면이 있습니다.
또한, 객체 생성이 복잡하기 때문에
빌더 패턴이나, 팩토리 패턴 등으로 보완할 필요성도 있습니다.
'개발 > Java' 카테고리의 다른 글
디자인 패턴 - Singleton Pattern (0) | 2016.03.22 |
---|---|
Jenkins + Git Timeout 설정 변경 방법 (0) | 2016.03.19 |
java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig (0) | 2016.03.08 |
디자인 패턴 - Observer Pattern (0) | 2016.03.07 |
Maven을 이용하여 실행 가능한 jar 만들기 (0) | 2016.03.04 |