프로그래밍 기술/Escort GoF의 디자인 패턴

18. 해석자 패턴(Interpreter Pattern) [Escort GoF의 디자인 패턴]

언제나휴일 2016. 4. 4. 15:03
반응형

18. 해석자 패턴(Interpreter Pattern)

 

18.1 개요

 

 해석자 패턴은 사용자가 표현하기 쉬운 표현을 사용하게 하고 이를 해석하는 개체를 통해 약속된 알고리즘을 수행하는 패턴입니다. SQL 쿼리문이나 Command 창에서 프로그램 실행 시 필요한 인자를 전달하는 경우 등에서 많이 사용될 수 있는 패턴입니다.

 

 해석자 패턴에서는 사용자가 원하는 다양한 명령을 쉽게 표현할 수 있게 구문 약속을 해야 합니다. 그리고 해석자에서는 이와 같이 약속된 구문을 입력 인자로 전달되었을 때 해석할 수 있어야 합니다. 가령 "2 Add 3" 과 같은 표현은 피 연산자:2, 연산자:+, 피 연산자:3 으로 해석될 수 있다는 것입니다.

 

 해석자 패턴을 사용하면 사용자가 다양한 명령을 쉬운 표현 방법으로 전달할 수 있습니다. 하지만, 너무 많은 명령어 조합을 해석자 패턴으로 적용한다면 정규화 과정에 들어가는 비용이 기하급수적으로 커질 수 있습니다. 비교적 사용자가 표현식의 문법이 단순할 수 있다면 효과적이겠지만, 그렇지 않다면 다른 방법을 사용하는 것이 나을 수 있습니다.

 

18. 2 시나리오

 

 EH Camera 회사의 객원 감수자로 활동을 하면서 개인적으로 만들었던 사진 관리 응용들의 일부 기능들이 요긴하게 사용하게 되었습니다. 하지만, 개인적으로 만들었던 응용과는 달리 좀 더 사용자가 편리하고 효과적으로 사진을 관리하고 보정할 수 있게 만들어야 했습니다. 이러한 이유로 많은 엔지니어가 사용자와 상호 작용하는 부분에 많은 비용이 들게 되더군요.

 

 좀 더 사용자가 편리하고 효과적으로 사진을 관리하고 보정할 수 있는 방법을 생각하다가 각 개인에 따라 사진 보정을 할 때 사용하는 기능은 개인에 따라 매크로를 제공하는 것이 나을 수 있다는 생각을 하게 되었습니다. 그리고 개인이 쉽게 매크로를 만들 수 있는 표현을 생각하게 되었고 이러한 매크로를 분석하여 포함된 기능들을 수행할 수 있게 설계해 보았습니다.

 

 설계에서는 사진을 보정하는 개체를 서로 체인 형태로 연결하고 보정 명령 구문을 해석하여 자신이 수행해야 할 부분에 대하여 해석할 수 있게 하였습니다. 이제는 사용자는 자신이 보정하고자 하는 종류를 매크로에 보관하는 초기 작업과 원하는 보정 구문을 추가하면 매크로 내부에 있는 각 보정 개체가 자신이 수행해야 할 구문을 분석합니다. 이 후 사용자는 보정할 사진을 넣으면 매크로에 보관된 각 보정 개체들이 알아서 보정 작업을 합니다. 이제 간략한 예광탄을 만들어 본 후에 이에 대해 다시 수정을 하거나 보완 작업을 해야겠어요.




AboutInterpreter.zip

//common.h

#pragma once

 

#pragma warning (disable:4996)

#include <iostream>

 

using std::cout;

using std::endl;

#include <vector>

using std::vector;

#include <string>

using std::string;

 

#include <iomanip>

using std::ios;

#include <algorithm>

 

#pragma warning(disable:4482)

 

//Picture.h

#pragma once

#include "Common.h"

class Picture

{

             string name;

             int tone;

             int brightness;

             int saturation;

public:

             Picture(string name,int tone,int brightness,int saturation);               

             void ChangeTone(int tone);

             void ChangeBrightness(int brightness);

             void ChangeSaturation(int saturation);

             void View()const;

};

 

//Picture.cpp

#include "Picture.h"

 

Picture::Picture(string name,int tone,int brightness,int saturation)

{

             this->name = name;

             this->tone = tone;

             this->brightness = brightness;

             this->saturation = saturation;

}

 

 

void Picture::ChangeTone(int tone)

{

             this->tone += tone;

}

void Picture::ChangeBrightness(int brightness)

{

             this->brightness += brightness;

 

}

void Picture::ChangeSaturation(int saturation)

{

             this->saturation += saturation;

}

 

void Picture::View()const

{

             cout<<"사진 파일 :"<<name<<endl;

             cout<<"    색조:"<<tone<<" 명도:"<<brightness<<" 채도:"<<saturation<<endl;

}

 

//Expression.h

#pragma once

 

#include "Picture.h"

class Expression

{

             Expression *next;

public:   

             Expression()

             {

                           next = 0;

             }           

             virtual string Interpret(string context)=0;           

 

             virtual void DoItWithPicture(Picture *picture)

             {

                           if(next)

                           {

                                        next->DoItWithPicture(picture);

                           }

             }

             void SetNext(Expression *next)

             {

                           this->next = next;

             }           

protected:

             string NextInterpret(string context)

             {

                           if(next)

                           {

                                        return next->Interpret(context);

                           }

                           return context;

             }

};

 

//BrighExpression.h

#pragma once

#include "Expression.h"

 

class BrighExpression :

             public Expression

{           

             int value;

public:   

             virtual string Interpret(string context)

             {           

                           value = 0;                         

                           int index = -1;                   

                           string be ="";

                           string af = "";                     

                           while( (index = context.find_first_of("B"))!=-1)

                           {                                      

                                        value += atoi(context.substr(index+strlen("B")).c_str());

                                        if(index>0)

                                        {

                                                     be = context.substr(0,index);

                                        }

                                        else

                                        {

                                                     be = "";

                                        }

                                        index = context.find(";",index);

                                        af = context.substr(index+1);

                                        context = be+af;   

                           }

                           return NextInterpret(context);

             }

             virtual void DoItWithPicture(Picture *picture)

             {

                           picture->ChangeBrightness(value);

                           Expression::DoItWithPicture(picture);                 

             }

};

 

//SatuExpression.h

#pragma once

#include "Expression.h"

class SatuExpression:

             public Expression

{

             int value;

public:

             virtual string Interpret(string context)

             {           

                           value = 0;

                           int index = -1;                   

                           string be ="";

                           string af = "";                     

                           while( (index = context.find_first_of("S"))!=-1)

                           {                                      

                                        value += atoi(context.substr(index+strlen("S")).c_str());                                

                                        if(index>0)

                                        {

                                                     be = context.substr(0,index);

                                        }

                                        else

                                        {

                                                     be = "";

                                        }

                                        index = context.find(";",index);

                                        af = context.substr(index+1);

                                        context = be+af;   

                           }

                           return NextInterpret(context);

             }

            

             virtual void DoItWithPicture(Picture *picture)

             {

                           picture->ChangeSaturation(value);

                           Expression::DoItWithPicture(picture);

             }

};

 

//ToneExpression.h

#pragma once

#include "Expression.h"

class ToneExpression:

             public Expression

{           

             int value;

public:

             virtual string Interpret(string context)

             {           

                           value = 0;                         

                           int index = -1;                   

                           string be ="";

                           string af = "";                     

                           while( (index = context.find_first_of("T"))!=-1)

                           {                                      

                                        value += atoi(context.substr(index+strlen("T")).c_str());

                                        if(index>0)

                                        {

                                                     be = context.substr(0,index);

                                        }

                                        else

                                        {

                                                     be = "";

                                        }

                                        index = context.find(";",index);

                                        af = context.substr(index+1);

                                        context = be+af;   

                           }

                           return NextInterpret(context);

             }

            

             virtual void DoItWithPicture(Picture *picture)

             {

                           picture->ChangeTone(value);

                           Expression::DoItWithPicture(picture);   

             }

};

 

//Macro.h

#pragma once

#include "ToneExpression.h"

#include "SatuExpression.h"

#include "BrightExpression.h"

 

class Macro

{

             Expression *head;

             Expression *tail;

             string context;

public:

             Macro(void);         

             void AddExpression(Expression *expression);

             void ChangePicture(Picture *picture);

             void AddContext(string context);

};

 

//Macro.cpp

#include "Macro.h"

 

Macro::Macro(void)

{

             head = tail = 0;

}

 

void Macro::AddExpression(Expression *expression)

{

             if(head)

             {

                           tail->SetNext(expression);

                           tail = expression;

             }

             else

             {

                           head = tail = expression;

             }

}

void Macro::ChangePicture(Picture *picture)

{           

             head->DoItWithPicture(picture);

}

void Macro::AddContext(string context)

{

             head->Interpret(context);     

}

 

//demo.cpp

#include "Macro.h"

 

int main()

{

             Expression *ex1 = new ToneExpression();

             Expression *ex2 = new BrighExpression();

             Expression *ex3 = new SatuExpression();

 

             Macro *macro = new Macro();

             macro->AddExpression(ex1);

             macro->AddExpression(ex2);

             macro->AddExpression(ex3);

            

             macro->AddContext("B 20;");

             macro->AddContext("B 20;T-12;S 10;B10;");

            

 

             Picture *picture = new Picture("현충사의 ",100,100,100);

             macro->ChangePicture(picture);

             picture->View();

 

             delete picture;       

             delete macro;

             delete ex1;delete ex2;delete ex3;

             return 0;

}


IT 전문가로 가는 길 Escort GoF의 디자인 패턴
국내도서
저자 : 장문석
출판 : 언제나휴일 2013.04.01
상세보기


 


반응형