학습목표 l 퍼싸드패턴과그적용 l 데코레이터패턴과그적용 l 실습문제 2

Similar documents
Microsoft PowerPoint - 11_DesignPatterns(2010).ppt [호환 모드]

JAVA PROGRAMMING 실습 08.다형성

(Microsoft PowerPoint - 11_DesignPatterns\(2008\).ppt [\310\243\310\257 \270\360\265\345])

PowerPoint 프레젠테이션

PowerPoint Presentation

rmi_박준용_final.PDF

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

Microsoft PowerPoint - 04-UDP Programming.ppt

07 자바의 다양한 클래스.key

Java Programing Environment

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

01-OOPConcepts(2).PDF

No Slide Title

12-file.key

PowerPoint Presentation

PowerPoint Presentation

PowerPoint Presentation

gnu-lee-oop-kor-lec06-3-chap7

비긴쿡-자바 00앞부속

PowerPoint Presentation

쉽게 풀어쓴 C 프로그래밍

Spring Data JPA Many To Many 양방향 관계 예제

Microsoft PowerPoint - Lect04.pptx

PowerPoint 프레젠테이션

제목

PowerPoint Presentation

PowerPoint Presentation

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - 2강

Microsoft PowerPoint - Java7.pptx

Microsoft PowerPoint - CSharp-10-예외처리

C++ Programming

PowerPoint Presentation

자바GUI실전프로그래밍2_장대원.PDF

5장.key

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

09-interface.key

쉽게 풀어쓴 C 프로그래밍

Microsoft PowerPoint - ÀÚ¹Ù08Àå-1.ppt

Java

JAVA PROGRAMMING 실습 02. 표준 입출력

Interstage5 SOAP서비스 설정 가이드

윤성우의 열혈 TCP/IP 소켓 프로그래밍

Spring Boot/JDBC JdbcTemplate/CRUD 예제

mytalk

05-class.key

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

fundamentalOfCommandPattern_calmglow_pattern_jstorm_1.0_f…

No Slide Title

02 C h a p t e r Java

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

OOP 소개

Chap12

어댑터뷰

class Sale void makelineitem(productspecification* spec, int qty) SalesLineItem* sl = new SalesLineItem(spec, qty); ; 2. 아래의액티비티다이어그램을보고 Java 또는 C ++,

PowerPoint Presentation

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

자바 프로그래밍

슬라이드 1

Design Issues

쉽게 풀어쓴 C 프로그래밍

1

슬라이드 1

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

chap10.PDF

JAVA PROGRAMMING 실습 09. 예외처리

Microsoft PowerPoint - 03-TCP Programming.ppt

JMF3_심빈구.PDF

IPAS-CDR사용자메뉴얼(EN/KOR)

목차 INDEX JSON? - JSON 개요 - JSONObject - JSONArray 서울시공공데이터 API 살펴보기 - 요청인자살펴보기 - Result Code - 출력값 HttpClient - HttpHelper 클래스작성 - JSONParser 클래스작성 공공

ch09

PowerPoint 프레젠테이션

제11장 프로세스와 쓰레드

PowerPoint 프레젠테이션

JAVA PROGRAMMING 실습 05. 객체의 활용

Java ...

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

10.0pt1height.7depth.3width±â10.0pt1height.7depth.3widthÃÊ10.0pt1height.7depth.3widthÅë10.0pt1height.7depth.3width°è10.0pt1height.7depth.3widthÇÁ10.0pt1height.7depth.3width·Î10.0pt1height.7depth.3width±×10.0pt1height.7depth.3width·¡10.0pt1height.7depth.3width¹Ö pt1height.7depth.3widthŬ10.0pt1height.7depth.3width·¡10.0pt1height.7depth.3width½º, 10.0pt1height.7depth.3width°´10.0pt1height.7depth.3widthü, 10.0pt1height.7depth.3widthº¯10.0pt1height.7depth.3width¼ö, 10.0pt1height.7depth.3width¸Þ10.0pt1height.7depth.3width¼Ò10.0pt1height.7depth.3widthµå

11 템플릿적용 - Java Program Performance Tuning (김명호기술이사)

제8장 자바 GUI 프로그래밍 II

신림프로그래머_클린코드.key

Microsoft PowerPoint - 13_UMLCoding(2010).pptx

PowerPoint Template

슬라이드 1

Network Programming

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

제목

PowerPoint 프레젠테이션

Microsoft PowerPoint - RMI.ppt

Cluster management software

gnu-lee-oop-kor-lec10-1-chap10

Microsoft PowerPoint - Chap12-OOP.ppt

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

쉽게 풀어쓴 C 프로그래밊

MasoJava4_Dongbin.PDF

Microsoft PowerPoint 장강의노트.ppt

Transcription:

객체지향설계와패턴 Lecture #10: 구조패턴 (1) Eun Man Choi emchoi@dgu.ac.kr

학습목표 l 퍼싸드패턴과그적용 l 데코레이터패턴과그적용 l 실습문제 2

구조패턴 l 더큰구조를형성하기위하여클래스와객체를어떻게합성하는가? l 상속기법이용 l 인터페이스, 구현을합성 l 독립적으로개발될클래스라이브러리의합성 l 구조화패턴 l 새로운기능을구현하기위하여객체를구성하는방식 l 런타임에객체구조를변경 l 유연성, 확장성 3

Pattern #6 퍼싸드패턴 l 패턴요약 l 패키지의기능을제공할수있는유일수단인인터페이스를정의 l 주의 l 클래스들을패키지로구성할필요는없음. 하나이상의클래스들이퍼싸드를위하여사용될수도있음 클래스패키지에인터페이스를제공하기위하여사용 4

퍼싸드패턴 : 동기 당신이입사해서처음맡은일은소규모의프로그램개발환경을만드는작업이다. 그리고, 이런유사한프로젝트들이많아이미회사내에는토큰분석기 (Scanner), 문법분석기 (Parser), 분석된코드를내부자료구조로재구성해주는빌더 (Program Node Builder) 등과기계어코드를생성하는코드생성기 (Code Generator) 들이클래스라이브러리로개발되어있다. 그러나, 라이브러리의각클래스기능들을이해하고, 클래스들간의상호작용하는메커니즘을분석하는것은상당히힘든일이다. 당신의주된작업은개발환경의 GUI 를만드는것이며, 이클래스라이브러리에게서원하는것은단지주어진소스코드를컴파일시키는기능이다. 왜클래스라이브러리내부구현과동작메커니즘을학습하는데소중한시간을낭비해야하는가? 5 Scanner ProgramNodeBuilder??? Parser CodeGenerator

퍼싸드패턴 : 동기 결국당신은다음유사한프로젝트나직장후배들을위하여기존클래스라이브러리의기능들을블랙박스방식으로쉽게사용할수있도록보완하기로하였다. 그방법은??? 내부는숨기고필요한기능들만외부에노출시키자 외부에노출되는인터페이스를단일화하자 외부에서앞의클래스라이브러리에원하는기능이 Compile 기능이라면, 외부에는 Compile interface 만노출시키고이라이브러리의내부구현과클래스들간의동작메커니즘은숨긴다. 6

퍼싸드패턴 : 동기 Client 외부에서는 Compiler 객체의 Compile() 함수만알면됨 7

퍼싸드패턴 : 동기 l Sample Code class Scanner { public: Scanner(istream&); virtual ~Scanner(); virtual Token& Scan(); private: istream& _inputstream; ; class Parser { public: Parser(); virtual ~Parser(); ; virtual void Parse(Scanner&, ProgramNodeBuilder&); class ProgramNodeBuilder { public: ProgramNodeBuilder(); virtual ProgramNode* NewVariable( char* variablename) const; virtual ProgramNode* NewAssignment( ProgramNode* variable, ProgramNode* expression ) const; virtual ProgramNode* NewReturnStatement( ProgramNode* value ) const; virtual ProgramNode* NewCondition( ProgramNode* condition, ProgramNode* truepart, ProgramNode* falsepart ) const; //... ProgramNode* GetRootNode(); private: ProgramNode* _node; ; 8

퍼싸드패턴 : 동기 class ProgramNode { public: // program node manipulation virtual void GetSourcePosition(int& line, int& index); //... // child manipulation virtual void Add(ProgramNode*); virtual void Remove(ProgramNode*); //... virtual void Traverse(CodeGenerator&); protected: ProgramNode(); ; class CodeGenerator { public: virtual void Visit(StatementNode*); virtual void Visit(ExpressionNode*); //... protected: CodeGenerator(BytecodeStream&); protected: BytecodeStream& _output; ; 9 class Compiler { public: Compiler(); ; façade interface virtual void Compile(istream&, BytecodeStream&); void Compiler::Compile ( istream& input, BytecodeStream& output) { Scanner scanner(input); ProgramNodeBuilder builder; Parser parser; parser.parse(scanner, builder); RISCCodeGenerator generator(output); ProgramNode* parsetree = builder.getrootnode(); parsetree->traverse(generator); 1 2 3 4

퍼싸드패턴 : 동기 l 외부에서서브시스템내의클래스들을개별적으로직접접근하지않 더라도그기능을쉽게사용할수있도록단일화된인터페이스를 (FaCade) 를제공한다. low-level 기능이필요할경우엔직접접근도허용할수있다. subsystem subsystem Facade 10

퍼싸드패턴 l 의도 l 서브시스템을대표하여 high-level 의단일화된인터페이스를제공함으로써서브시스템의사용을더욱쉽게만들어준다. l 동기 l 적용 l 복잡한서브시스템을대표하는간단한인터페이스를작성하기원할때 l Client code 와서브시스템내의클래스들과의존관계가많아이를줄이고자할때 l 서브시스템을층구조 (layer architecture) 의하나로만들고자원할때 11

퍼싸드패턴 l 구조 subsystem Facade 12

퍼싸드패턴의구조와기능 13

적용사례 1: 온라인쇼핑몰 q 적용후 14

적용사례 2: 자산급여관리 l 자산급여시스템 l 시스템 : CompanyAsset, Staffemployee l 인터페이스 : Asset, Employee l 퍼싸드클래스 : CompanyFascade 15

서브시스템 class StaffEmployee implements Employee { private String name; private float salary; StaffEmployee(String name, float salary) { this.name = name; this.salary = salary; public String getname() { return name; public float getsalary() { return salary; public String tostring() { return ("Name: "+getname()+" Salary: "+getsalary()); class CompanyAsset implements Asset { String description; int number; public CompanyAsset(String desc,int num) { this.description = desc; this.number = num; public String getassetdescription() { return description; public int getassetnumber() { return number; public String tostring() { return ("Description: "+getassetdescription()+" Number: "+getassetnumber()); 16

퍼싸드인터페이스 class CompanyFacade { Map assets; Map employees; public CompanyFacade() { assets = AssetFactory.getAssets(); employees = EmployeeFactory.getEmployees(); public String companyreport() { StringBuffer sb= new StringBuffer(); sb.append("assets\n"); Iterator iterator= assets.values().iterator(); while (iterator.hasnext()) { Asset asset = (Asset)iterator.next(); sb.append(asset.tostring()+"\n"); sb.append("employees\n"); iterator= employees.values().iterator(); 17

퍼싸드인터페이스 while (iterator.hasnext()) { Employee emp= (Employee)iterator.next(); sb.append(emp.tostring()+"\n"); return sb.tostring(); public String getemployeeinfo(string name) { Employee emp= (Employee) employees.get(name); return emp.tostring(); public String getassetinfo(string name) { Asset asset = (Asset) assets.get(name); return asset.tostring(); 18

클라이언트 class Client { public static void main(string args[]) { CompanyFacade company = new CompanyFacade(); System.out.println(company.getEmployeeInfo("kim")); System.out.println(company.getAssetInfo("Chair")); System.out.println(company.companyReport()); 19

적용사례 #3: 은행시스템 1. 어플리케이션은도입부를디스플레이한다. ( 모든출력은콘솔로이루어진다.) 2. 사용자가떠날때까지다음을반복한다. 2.1 고객이름리스트디스플레이 2.2 고객이름을선택하도록프롬프트 2.3 고객이름을등록 2.4 고객에대한정보출력 2.5 계좌번호를프롬프트 2.6 고객잔고를출력 2.7 예금액을프롬프트 2.8 예금액을등록 20

Using Façade to Access Bank Customers AccountException CustomerException Customer getcustomername() getnumaccounts() getpersonalnote() getaccount( int ) Account getaccountnum() deposit( int ) getbalance() framework BankCustomer 1..n BankAccount IntroMessage Client main() bankcustomers 21 BankCustomers dodeposit( int amt, Customer cust, Account acc ) getbankaccount( Customer cust, int accnum ) getbankcustomer( String custname ) introduceapplication() «facade»

은행시스템출력 22

원시코드 : 은행시스템 package bankcustomers; import framework.*; /*** Simplified bank account. */ class BankAccount implements Account { private int balance = 0; private int number = 999; public BankAccount() { super(); public BankAccount(int anaccountnumber) { super(); number = anaccountnumber; public int getaccountnum() { return number; public int getbalance() { return balance; public void deposit(int adepositamount) { this.balance += adepositamount; 23 package bankcustomers; import framework.*; import java.util.*; public class BankCustomers { // Note "public" private static BankCustomers bankcustomers = new BankCustomers(); private static Hashtable bankcustomertable = new Hashtable(); static // initialize customers{ Vector ableaccounts = new Vector(); ableaccounts.addelement(new BankAccount(1)); ableaccounts.addelement(new BankAccount(22)); ableaccounts.addelement(new BankAccount(333)); bankcustomertable.put("able", // the name as key new BankCustomer("Able", "Gentleman and longtime customer", ableaccounts));

원시코드 : 은행시스템퍼싸드 public static Customer getbankcustomer(string aname) throws CustomerException { Customer returncustomer = (Customer) bankcustomertable.get(aname); if (returncustomer!= null) // could not find it return returncustomer; else throw new CustomerException("No customer with this name"); public static BankCustomers getbankcustomers() { 24 return bankcustomers; public Account getbankaccount(customer acustomer, int anaccountnum) throws AccountException { Account currentaccount; String acustomername = acustomer.getcustomername(); String customername = " "; for (Enumeration enumeration = bankcustomertable.keys(); enumeration.hasmoreelements(); ) customername = ( (Customer) bankcustomertable.get(enumeration.nexteleme nt())). getcustomername(); if (acustomername.equals(customername)) for (int j = 0; j < acustomer.getnumaccounts(); ++j) { currentaccount = acustomer.getaccount(j); if (currentaccount.getaccountnum() == anaccountnum) return currentaccount; throw new AccountException("No customer with this name");

원시코드 : 은행시스템퍼싸드 public void listcustomers() { { System.out.println("These are the customers to choose from."); for (Enumeration enumeration = bankcustomertable.keys(); enumeration.hasmoreelements(); ) System.out.println(enumeration.nextEle ment()); public void dodeposit(int anamount, Customer acustomer, Account anaccount) { anaccount.deposit(anamount); System.out.println("Deposited " + anamount + " into the account of " + me()); acustomer.getcustomerna public static void introduceapplication() { IntroMessage.displayIntroductionToCon sole(); 25

적용사례 4: 홈씨어터

퍼싸드없다면

퍼싸드적용

홈씨어터퍼싸드 public class HomeTheaterFacade { Amplifier amp; Tuner tuner; DvdPlayer dvd; CdPlayer cd; Projector projector; TheaterLights lights; Screen screen; PopcornPopper popper; public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd, CdPlayer cd, Projector projector, Screen screen, TheaterLights lights, PopcornPopper popper) {

홈씨어터퍼싸드 this.amp = amp; this.tuner = tuner; this.dvd = dvd; this.cd = cd; this.projector = projector; this.screen = screen; this.lights = lights; this.popper = popper; public void watchmovie(string movie) { System.out.println("Get ready to watch a movie..."); popper.on(); popper.pop(); lights.dim(10); screen.down(); projector.on(); projector.widescreenmode(); amp.on(); amp.setdvd(dvd); amp.setsurroundsound(); amp.setvolume(5); dvd.on(); dvd.play(movie);

홈씨어터퍼싸드 public class CdPlayer { String description; int currenttrack; Amplifier amplifier; String title; public CdPlayer(String description, Amplifier amplifier) { this.description = description; this.amplifier = amplifier; public void on() { System.out.println(description + " on"); public void off() { System.out.println(description + " off"); public void eject() { title = null; System.out.println(description + " eject"); public void play(string title) { this.title = title; currenttrack = 0; System.out.println(description + " playing \"" + title + "\"");

홈씨어터퍼싸드사용 public class HomeTheaterTestDrive { public static void main(string[] args) { Amplifier amp = new Amplifier("Top-O-Line Amplifier"); Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp); DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp); CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp); Projector projector = new Projector("Top-O-Line Projector", dvd); TheaterLights lights = new TheaterLights("Theater Ceiling Lights"); Screen screen = new Screen("Theater Screen"); PopcornPopper popper = new PopcornPopper("Popcorn Popper"); HomeTheaterFacade hometheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, screen, lights, popper); hometheater.watchmovie("raiders of the Lost Ark"); hometheater.endmovie();

퍼싸드정리 서브시스템을더사용하기쉽도록통합된상위층의인터페이스를제공.

Pattern #7 데코레이터패턴 런터임에객체의기능을추가하기위하여사용 l 패턴요약 l 객체에동적으로추가적인기능을추가 l 주의 l 다른객체에영향을주지않으면서런타임에개개의객체에다른기능을추가하고싶을때 l 상속은컴파일타임에추가기능이확정적 34

데코레이터패턴 : 동기 당신은 GUI Framework 설계업무를맡았다. 화면구성요소들은일반적으로가장기본적인화면으로부터조금씩모습이나기능을확장시켜나간다. 예를들면단순히특정영역에문자열을보여주는 TextView 가있고, 여기에스크롤기능을추가할수있으며, 또한바깥테두리효과를추가할수있다. 기본객체에조금씩기능을추가시켜나가고자할때적절한객체지향적설계는? aborderdecorator ascrolldecorator Some applications would benefit from using objects to model evey aspect of their functionality, atextview Some applications would ben efit from using objects to model evey aspect of their functionality, 35

데코레이터패턴 : 동기 l 해결방안 1: 상속을이용하여조금씩기능을추가해나간다. TextView ScrolledTextView 문제점은없을까? BorderScrolledTextView 36

데코레이터패턴 : 동기 상속방식의문제점 TextView뿐만아니라, List, Panel, TreeView,.. 등에도 Scroll과 Border 기능을추가하려면, 각클래스별로 ScrolledName, BorderScrolledName 두개의클래스를더만들어야한다. 만일 Scroll 기능없이 Border만추가하려면? 각클래스별로 BorderName 클래스를작성하여야한다. 화면구성클래스가 N개에적용될새로운추가기능을넣을때마다, N개의새로운하위클래스가작성된다. ( 기능들간의조합을생각하면훨씬많아짐 ) 문제발생의원인은상속관계를사용함으로써추가하려는기능들이화면구성클래스와결합되어정적으로 (static) 고정되어버리기때문이다. 37

데코레이터패턴 : 동기 l 해결방안 2 화면구성클래스와추가기능 (decorator) 들을분리하고, 하나의화면구성클래스에여러개의기능 (decorator) 들이연결되도록구성한다. Client draw draw draw aborderdecorator ascrolldecorator atextview aborderdecorator ascrolldecorator 상속대신 Delegation 이용 atextview Some applications would ben efit from using objects to model evey aspect of their functionality, 38

데코레이터패턴 : 동기 l 해결방안 2: 클래스다이어그램 기본화면구성클래스 앞에연결되어있는객체의 Draw() 호출후에자신의추가기능수행 추가기능클래스들 (decorator) 39

데코레이터패턴 l 의도 l 객체에동적으로추가적인역할 (responsibility) 을덧붙이기 l 기능을확장하는데있어서상속방식이아닌, 더욱유연한기능확장방안을제공 l 별칭 l Wrapper l 적용 l 다른객체에영향을주지않으면서, 동적으로개개의객체에다른역할을추가시키고자할때 l 객체의역할을동적으로늘이거나줄이고자할때 l Subclassing 을통한역할추가가힘들때 40

데코레이터패턴 l 구조 decorator 는 1 개의 component 와연결 41 연결된 component 의연산을수행후, 현 decorator 의추가된기능수행

데코레이터패턴 l 구성요소 l Component(Visual Component) 동적으로기능을확장받을객체들의인터페이스정의 l ConcreteComponent(TextView) 동적으로기능을확장받을객체정의 l Decorator 하나의 Component 객체와연결이되어있음. Component 인터페이스를따름. l ConcreteDecorator (BorderDecorator, ScrollDecorator) 연결되어있는 Component 객체에기능을확장 42

데코레이터패턴 l 협력도 43

데코레이터패턴 l 결과 l 상속보다는더융통성이좋아짐 l 클래스기능이과다하게되는것을피할수있음 기능을확장받을객체자체는단순하게유지 데코레이터객체와의조합을통하여기능을확장 l 데코레이터와컴포넌트는동일한것이아님 Decorator 객체가 Component 객체를투명하게감싸긴하지만, 연결되어있는객체자체는아니다. 그러므로, Component Identity를가정하여코딩하면안된다. l Lots of little objects Decorator pattern 을사용하면, 비슷하게보이는작은객체들이시스템을이루게되는경우가종종있다. 이경우설계를잘이해하는사람들에게는쉽게 customize 할수있지만, 설계를이해하고 debug 하기는힘들다. 44

데코레이터패턴 l 구현 l 인터페이스적합성 Decorator 객체는 Component 인터페이스를지원하여야한다. l 추상데코레이터클래스의생략 확장될기능이한가지라면, abstract Decorator class 는생략하고 ConcreteDecorator class 를사용할수있다. l 컴포넌트클래스를가볍게유지 핵심적인것인아닌기능들은 Decorator 로만듦으로써 ConcreteComponent 자체를가볍게만들수있다. l Changing the skin of an object versus changing its entrails Decorator pattern 은 simple 한 component 객체의외관 ( 모습 or 기능 ) 을변경하는데주로활용되는반면, complex 한 component 의내부기능을변경할때는 Strategy pattern 이주로이용된다. 45

데코레이터패턴 l 사례코드 46 class VisualComponent { public: VisualComponent(); virtual void Draw(); virtual void Resize(); //... ; class Decorator : public VisualComponent { public: Decorator(VisualComponent*); virtual void Draw () { _component->draw(); virtual void Resize () { _component->resize(); //... private: VisualComponent* _component; ; 요청사항 forwarding

데코레이터패턴 class BorderDecorator : public Decorator { public: BorderDecorator(VisualComponent*, int borderwidth); virtual void Draw () { Decorator::Draw(); DrawBorder(_width); private: void DrawBorder(int); private: int _width; ; class ScrollDecorator : public Decorator { public: ScrollDecorator(VisualComponent*); ; class TextView : public VisualComponent { ; 47 앞에연결되어있는객체의 Draw() 호출후에자신의추가기능수행 // Client Code // textview 객체에 Scroll, Border 기능확장 Window* window = new Window; TextView* textview = new TextView; window->setcontents(textview); window->setcontents( new BorderDecorator( new ScrollDecorator(textView), 1 ) ); textview 에 ScrollDecorator, BorderDecorator 를생성하여연결시킴

데코레이터패턴 l 알려진사례 l Many object-oriented user interface toolkits use decorators l 연관패턴 InterViews, ET++, ObjectWorks\Smalltalk class library, l 어뎁터패턴과달리데코레이터패턴은객체의인터페이스를변경하는것이아니라, 객체의역할들 (responsibilities) 을바꾸는데그목적이있다. l 데코레이터패턴은컴포지트패턴의특별한경우 (child 가하나인경우 ) 로볼수있다. 그러나, 이역시사용의도가서로다르다. l Strategy pattern 은복잡한 component 객체의내부기능을변경하는데주로이용되는반면, 데코레이터패턴은 simple 한 component 객체의외관 ( 모습 or 기능 ) 을변경하는데주로이용된다. 48

사례 1: 아바타시스템 패턴미적용 데코레이터패턴적용 49

사례 2: HTML 로데코레이션 abstract class TextComponent { protected String textvalue; public void settext(string textvalue) { this.textvalue = textvalue; public String gettext() { return this.textvalue; public abstract void displaytext(); class StdoutTextComponent extends TextComponent { public void displaytext() { System.out.println(textValue); abstract class TextComponentDecorator extends TextComponent { protected TextComponent textcomponent; public void settextcomponent(textcomponent textcomponent) { this.textcomponent = textcomponent; public void displaytext() { textcomponent.displaytext(); public String gettext() { return textcomponent.gettext(); public void settext(string textvalue) { textcomponent.settext(textvalue); 50

사례 2: HTML 로데코레이션 class HTMLTextComponentDecorator extends TextComponentDecorator { public void displaytext() { String oldtext = gettext(); settext("<strong>" + gettext() + "</STRONG>"); super.displaytext(); settext(oldtext); public class DecoratorExample { public DecoratorExample(TextComponent textcomponent) { textcomponent.displaytext(); public static void main(string args[]) { StdoutTextComponent textcomponent1 = new StdoutTextComponent(); textcomponent1.settext("hello, world"); new DecoratorExample(textComponent1); HTMLTextComponentDecorator htcd = new HTMLTextComponentDecorator(); htcd.settextcomponent(textcomponent1); new DecoratorExample(htcd); 51

Use of Decorator in java.io Reader 1 InputStream InputStreamReader BufferedReader 52

java.io Decorator example : BufferedStreamReader :InputStreamReader System.in:InputStream 53