728x90

팩토리 패턴이란 객체들의 동적 생성을 책임지고 관리하는 팩토리를 만들어서 확장이나 관리를 효율적으로 할 수 있게 하는 패턴이다.

 

심플 팩토리 패턴이란 나중에 나올 팩토리 메서드 패턴과, 추상 팩토리 패턴의 기본이 되는 부분이자, 단순하게 객체를 생성하여 넘겨주는 역할을 하는 패턴이다.

 

class Pizza
{
protected:
    char name[256];
    char dough[256];
    char sauce[256];
public:
    Pizza(void) {};
    virtual ~Pizza(void) {};
public:
    inline char* getName() { return name; }

    virtual void prepare() /// 피자 준비
    {
        cout<<"============================="<<endl;
        cout<<name<<"를 준비합니다."<<endl;
        cout<<dough<<"도우 반죽중..."<<endl;
        cout<<sauce<<"소스 추가중..."<<endl;
    }
    virtual void bake() /// 피자 굽기
    {
        cout<<name<<"를 굽습니다."<<endl;
    }
    virtual void cut() /// 피자 자르기
    {
        cout<<name<<"를 자릅니다."<<endl;
    }
    virtual void box() /// 피자 포장하기
    {
        cout<<name<<"를 포장합니다."<<endl;
    }
};

class PepperoniPizza : public Pizza
{
public:
    PepperoniPizza(void)
    {
        strcpy_s( name, "페퍼로니 피자" );
        strcpy_s( dough, "일반 " );
        strcpy_s( sauce, "마리나라 " );
    };
    ~PepperoniPizza(void) {};
};

class ChickenPizza : public Pizza
{
public:
    ChickenPizza(void)
    {
        strcpy_s( name, "치킨 피자" );
        strcpy_s( dough, "쌀 " );
        strcpy_s( sauce, "토마토 " );
    };
    ~ChickenPizza(void) {};
};

class SimplePizzaFactory
{
public:
    SimplePizzaFactory() { cout<<"피자 머신 ON"<<endl; }
    ~SimplePizzaFactory() { cout<<"피자 머신 OFF"<<endl; }
public:
    Pizza* createPizza( int number )
    {
        Pizza* object = NULL;
        switch( number )
        {
        case 1: /// 페퍼로니 피자
            object = new PepperoniPizza();
            break;
        case 2: /// 치킨 피자
            object = new ChickenPizza();
            break;
        default:
            return object;
        }
        return object;
    };
};

 

 

 

PepperoniPizza 클래스와 ChickenPizze 클래스는 Pizza 클래스를 상속 받고 있고

Pizza 클래스에는 피자들의 공통되는 메소드 들이 정의 되어 있다.

SimplePizzaFactory 클래스에는 createPizza 메소드에서 동적으로 객체들을 생성해서 넘겨주는 역할을 하고 있다.

 

후에는 새로운 피자를 추가하거나, 혹은 기존 피자 종류를 삭제해야한다면 simplePizzaFactory 클래스안에서 수정해주기만 하면 된다.

 

*심플 팩토리는 하나의 객체 안에서 수많은 서로 다른 객체들이 동적으로 생성될때 사용하면 유용하다.

 

 

728x90
Posted by 정망스
,

옵져버(Observer) 패턴

기타 2016. 10. 13. 08:55
728x90

옵져버 패턴은 어떤 객체의 상태가 변하면 그 객체의 상태에 의존성을 가진 다른 객체들이 그 변화를 통지 받고 자동으로 업데이트하게 하는 패턴.

 

쉽게 말하면 (전파자 - 전파를 받는 자들 (일대다))의 관계로 한명이 여러명에게 전달을 하는 거다.

 

아래는 이해하기 쉽도록 스타크래프트의 마린의 상태를 예로 들어 옵져버 패턴을 적용해본 예시이다.

 

마린의 상태는 내가 보는 모니터의 메인화면과, 캐릭터의 상태창, 적의화면에 모두 동일하게 체력상태가 보여야 된다는 것이다.

 

마린의 체력 상태가 변경된다면 메인화면, 상태창, 적의화면이라는 전파를 받는 자들에게 상태를 업데이트하라고 명령을 하는것이다.

 

001.using System;

002.using System.Collections.Generic;
003.using System.Linq;
004.using System.Text;
005.
006.namespace Observer
007.{
008. class Program
009. {
010. static void Main(string[] args)
011. {
012.
013. Marine ourMarine = new Marine("아군 마린", 100);
014. ourMarine.Attach(new MainScreen());
015. ourMarine.Attach(new StatusScreen());
016. ourMarine.Attach(new EnemyScreen());
017.
018. ourMarine.Health = 60;
019. ourMarine.Health = 40;
020.
021. Console.ReadKey();
022. }
023.
024. abstract class Unit
025. {
026. private string name;
027. private int health;
028. private List<UnitViewer> unitViewers = new List<UnitViewer>();
029.
030. public Unit(string name, int health)
031. {
032. this.name = name;
033. this.health = health;
034. }
035.
036. public void Attach(UnitViewer investor)
037. {
038. unitViewers.Add(investor);
039. }
040.
041. public void Detach(UnitViewer investor)
042. {
043. unitViewers.Remove(investor);
044. }
045.
046. public void Notify()
047. {
048. foreach (UnitViewer unitviewr in unitViewers)
049. {
050. unitviewr.Update(this);
051. }
052. }
053.
054.
055. public int Health
056. {
057. get { return health; }
058. set
059. {
060. health = value;
061. Notify();
062. }
063. }
064.
065. public string Name
066. {
067. get { return name; }
068. }
069. }
070.
071. class Marine : Unit
072. {
073. public Marine(string name, int health)
074. : base(name, health)
075. {
076. }
077. }
078.
079.
080. interface UnitViewer
081. {
082. void Update(Unit unit);
083. }
084.
085.
086. class MainScreen : UnitViewer
087. {
088. private Unit unit;
089.
090. public void Update(Unit _unit)
091. {
092. this.unit = _unit;
093. Console.WriteLine("메인화면 {0} 상태 변경 : 체력 {1}", this.unit.Name, this.unit.Health.ToString());
094. }
095.
096. public Unit Unit
097. {
098. get { return unit; }
099. set { unit = value; }
100. }
101. }
102.
103. class StatusScreen : UnitViewer
104. {
105. private Unit unit;
106.
107. public void Update(Unit _unit)
108. {
109. this.unit = _unit;
110. Console.WriteLine("상태창 {0} 상태 변경 : 체력 {1}", this.unit.Name, this.unit.Health.ToString());
111. }
112.
113. public Unit Unit
114. {
115. get { return unit; }
116. set { unit = value; }
117. }
118. }
119.
120. class EnemyScreen : UnitViewer
121. {
122. private Unit unit;
123.
124. public void Update(Unit _unit)
125. {
126. this.unit = _unit;
127. Console.WriteLine("적 상태창 {0} 상태 변경 : 체력 {1}", this.unit.Name, this.unit.Health.ToString());
128. }
129.
130. public Unit Unit
131. {
132. get { return unit; }
133. set { unit = value; }
134. }
135. }
136. }
137.}

 

 

Marine 클래스는 Unit이라는 클래스를 상속받고 있고, Attach 메소드를 통해서 UnitViewer(메인화면), StatusScreen(상태창), EnemyScreen(적 상태창) 이 3개의 클래스들 즉 전파를 받을 자들을 등록한다.

 

위 3개의 클래스들은 UnitViewer라는 인터페이스를 상속받고 있고 인터페이스 안에 있는 Update 함수를 각 클래스들에 맞게 재정의 해주고 있다.

 

이제 마린의 체력 상태가 바뀌게 되면 체력 수치를 바꾸고 Notify 메소드를 통해 등록되어있는 전파자들에게 Update 함수를 실행하도록 한다.

 

728x90
Posted by 정망스
,

winsock i/o 모델 종류..

기타 2016. 10. 10. 19:04
728x90

Windows용 Winsock 네트워크 프로그램의 모델은 다음 6가지로 나뉜다. 아래로 갈수록 더 좋은 성능을 보인다.

1. Blocking Model

- 단순한 구조로 각 connection 마다 thread를 할당하여 처리. blocking 함수를 사용

2. Select Model

- select함수를 이용

3. WSAAsyncSelect Model

- WASAsyncSelect함수이용. 소켓이벤트발생시 윈도우즈 메시지 통보 받음

4. WSAEventSelect Model

- WASEventSelect함수이용. Event Object를 이용하여 소켓이벤트 통보 받음

5. Overlapped I/O Model

-  Overlapped 구조체 사용. 비동기적인 I/O작업수행

6. Completion Port (IOCP)

- Win32 커널오브젝트를 사용. 재사용 가능한 쓰레드 풀유지.

 

728x90
Posted by 정망스
,
728x90

처음 프로그래밍을 할때부터 이클립스로 보통 export 하면

생기는 라이브러리가 .jar 파일을 많이 접했는데 이게 예전부터 보아왔고 사용했고, 그래서 지금도 엄청 익숙한데

 

저번 메시지 푸쉬 기능을 한번 해보면서

 

좀 내 기준에선 새로운걸 발견한 듯 하여 까먹지 않으려 일단 적어 본다.

 

결론부터 적자면 aar 이라는 나에게 있어서는 새롭게 보는 라이브러리 형태 파일인대.

 

기존에 jar 파일 형식은 유니티에서 약간 사용하기가 번거로운 부분이 많은가 보다 ..

 

보통 안드로이드에 필요한 리소스들, xml등은 res 파일에 추가 되는데 유니티에서 안드로이드와

같이 작업하긴 위해선 이 jar 파일과 + res 파일을 같이 옴겨서 사용해야 햇나보다.

 

리소스를 사용하지 않으면 문제가 없을테지만 말이다.

 

버전업 되어 나온지 유니티 5 이상부턴 aar 이라는 안드로이드 프로젝트 라이브러리 또한

사용할수 있게 지원한다는 것 같다.

 

aar 파일은 이미지, xml 등을 모두 같이 한번에 모듈화 할수 있는 듯 하다.

 

나도 최근에 google play services를 사용해보려고 라이브러리를 찾던중 아무리 찾아도 안보이길래

 

검색을 통해서 알아보니 sdk 매니저를 통해 받은 경로를 뒤져보니 각각에 필요한 기능들 별로 aar 파일이 제공되어 있었다.

 

아무래도 안드로이드를 기반으로 만드는거면 aar을 더 권장하는 목적으로 그러는거 같기도 하고.. (이건 그냥 내 생각..)

 

아무튼 새로운걸 알아 냈다.~

728x90
Posted by 정망스
,
728x90

 

 

 

#include "Calculator.h"

#include <stdio.h>

#include <stdlib.h>


char* PostfixNotation(char* str)

{

//stridx->후기표기법으로 수정 할 문자열 인덱스,idx->변환 된 문자가 들어갈 인덱스

int stridx=0,idx=0;

char PostStr[SIZE_ARR];

Stack s;

StackInit(&s);

 

while(str[stridx]>0)

{

char a=str[stridx];


if(a>='0'&&a<='9') //피연산자는 바로 PostStr에 저장

{

PostStr[idx]=a;

stridx++;

idx++;

}

else

{

switch(a) // a가 연산자일경우 : 우선순위 *,/ > +,- > ( [ ')'나오면 '('나올때까지 Pop]

{

case '+':case '-'

{

if(SIsEmpty(&s)) // 스택에 비었을 경우 바로 Push

{

SPush(&s,a);

stridx++;

}

else if(SPeek(&s)=='(') // '('있을경우 그대로 Push

{

SPush(&s,a);

stridx++;

}

else // 같은 연산자이거나, *혹은/연산자가 있을경우 전부 Pop한 후 Push

{

while(!SIsEmpty(&s))

{

PostStr[idx]=SPop(&s);

idx++;

}

SPush(&s,a);

stridx++;

}

break;

}

case '*':case '/': //우선순위가 가장 높기 때문에 그대로 Push

{

SPush(&s,a);

stridx++;

break;

}

case '(': //가장 낮은 우선순위이면서 특이한 케이스 그대로 Push

{

SPush(&s,a);

stridx++;

break;

}

case ')': //'('나올 때 까지 모두 Pop시켜줌

{

while(SPeek(&s)!='(')

{

PostStr[idx]=SPop(&s);

idx++;

}

SPop(&s);

stridx++;

break;

}

}

}

}


while(!SIsEmpty(&s))

{

PostStr[idx]=SPop(&s);

idx++;

}

return PostStr;

}


void SInit(IntStack *ps)

{

ps->TopIndex=-1;

}


int SEmpty(IntStack *ps)

{

if(ps->TopIndex==-1)

return TRUE;

else

return FALSE;

}


int SFull(IntStack *ps)

{

if(ps->TopIndex==SIZE_ARR)

return TRUE;

else

return FALSE;

}



void Push(IntStack *ps,int data)

{

ps->arr[++ps->TopIndex]=data;

}


int Pop(IntStack *ps)

{

return ps->arr[ps->TopIndex--];

}


int Peek(IntStack *ps)

{

return ps->arr[ps->TopIndex];

}



//피연산자는 스택에 바로 Push, 연산자가 나올 때마다 스택 Pop두번해 피연산자 2개 호출 후 연산 뒤 다시 스택에 Push

int CalculatePost(char* str)

{

int idx=0;

int i=0;

IntStack s;

SInit(&s);


while(str[idx]>0)

{

int num=0;


if(str[idx]>='0'&&str[idx]<='9')

{

Push(&s,(str[idx]-'0'));

idx++;

}

else

{

switch(str[idx])

{

case '+':

{

num=Pop(&s)+Pop(&s);

Push(&s,num);

idx++;

break;

}

case '-':

{

num=Pop(&s)-Pop(&s);

Push(&s,num);

idx++;

break;

}

case '*':

{

num=Pop(&s)*Pop(&s);

Push(&s,num);

idx++;

break;

}

case '/':

{

num=Pop(&s)/Pop(&s);

Push(&s,num);

idx++;

break;

}

}

}

}


return Pop(&s);

}

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침