블로그 이미지
Kanais
Researcher & Developer 퍼즐을 완성하려면 퍼즐 조각들을 하나 둘씩 맞춰나가야 한다. 인생의 퍼즐 조각들을 하나 둘씩 맞춰나가다 보면 인생이란 퍼즐도 완성되는 날이 오려나...?

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

05-11 13:40

Recent Post

Recent Comment

Recent Trackback

Archive

2015. 4. 16. 10:10 Programming/Design Pattern



참고 서적 : GOF의 디자인패턴 – Addison Wesley – 에릭감마, 리처드 헬름, 랄프 존슨, 존 블리시디스 지음. 김정아 옮김.


 BuilderTest.zip


Builder

복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴입니다.

 

Builder패턴의 의도

복잡한 개체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공할 수 있도록 합니다.

 

활용성

빌더 패턴은 다음의 경우에 사용합니다.

-      복합 개체의 생성 알고리즘이 이를 합성하는 요소 객체들이 무엇인지 이들의 조립 방법에 독립적일 때

-      합성할 개체들의 표현이 서로 다르더라도 생성 절차에서 이를 지원해야 할 때

 

구조

 

 

 

Builder : Product개체의 일부 요소들을 생성하기 위한 추상 인터페이스를 정의합니다.

ConcreteBuilder : Builder클래스에 정의된 인터페이스를 구현하며, 제품의 부품들을 모아 빌더를 복합합니다.

Director : Builder 인터페이스를 사용하는 개체를 합성합니다.

Product : 생성할 복합개체를 표현합니다. ConcreteBuilder는 제품(Product)의 내부 표현을 구축하고 복합 개체가 어떻게 구성되는지에 관한 절차를 정의합니다.

 

결과

빌더 패턴의 장단점은 다음과 같습니다.

 

장점

—  제품에 대한 내부 표현의 다양화

Builder클래스는 Director클래스에게 개체를 생성할 수 있는 인터페이스를 제공하고 생성 되는 개체의 내부구조나 표현방식 등은 builder클래스 내부로 숨기는 형태입니다. 개체를 복합할 때는 builder에 정의된 추상 인터페이스를 통해 사용자가 동작하기 때문에 새로운 제품의 표현 방법이나 제품의 복합 방법이 바뀔 때 builder 클래스의 상속을 통해 새로운 서브클래스를 정의하면 됩니다.

 

—  생성과 표현에 필요한 코드 분리

생성과 표현에 필요한 코드를 분리시켜 줌으로써 서로 간의 독립성을 줍니다. 이를 통해 Builder와 Director클래스는 서로 독립적으로 수정되거나 재 사용될 수 있습니다.

 

—  복합 개체를 생성하는 절차의 세밀화

복합 개체를 생성하는 절차를 좀더 세밀하게 나눌 수 있습니다. Builder패턴은 개체를 한꺼번에 생성하는 것이 아니라,부분 부분을 생성한 후 최종 결과를 얻어가는 방식이므로, 개체 생성 과정을 좀더 세밀히 제어할 수 있습니다.

 

단점

—  새로운 종류의 개체생성을 추가하기는 쉬우나, 개체를 구성하는 각 부분을 추가하기는 어려움

 

Builder패턴은 새로운 종류의 개체생성을 추가하기는 쉬우나, 개체를 구성하는 각 부분을 추가하기는 어렵습니다. Builder패턴에 새로운 인터페이스를 추가하면 Director클래스와 Builder클래스의 상속하는 concreteBuilder클래스를 모두 클래스를 수정해야 하는 문제가 생깁니다.

따라서 Builder패턴을 적용하고자 할 경우에는 생성되는 개체를 구성하는 부분들을 명확히 해서 수정 할 부분이 없게 하는 것이 중요합니다.

 

예제 소스

 

Class Diagram

 

소스 설명

class Element

    {

        public string Name

        {

            get;

            private set;

        }

        public string WallName

        {

            get;

            private set;

        }

        public int Wall

        {

            get;

            private set;

        }

        public string FloorName

        {

            get;

            private set;

        }

        public int Floor

        {

            get;

            private set;

        }

        ArrayList others = new ArrayList();

        public Element(string name)

        {

            Name = name;

            Console.WriteLine("{0}집을 짓기 시작합니다", Name);

            Thread.Sleep(1000);

        }

        public void SetWall(string name, int num)

        {

            WallName = name;

            Wall = num;

            Console.WriteLine("{0}개의 재료를 소모하여 {1}벽을 세우고 있습니다.", Wall, WallName);

            Thread.Sleep(1000);

        }

        public void SetFloor(string name, int num)

        {

            FloorName = name;

            Floor = num;

            Console.WriteLine("{0}개의 재료를 소모하여 {1}바닥을 깔고 있습니다.", FloorName, Floor);

        }

        public void SetOthers(object other)

        {

            others.Add(other);

            Console.WriteLine("{0} 재료도 사용합니다.",other);

            Thread.Sleep(500);

        }

        public override string ToString()

        {

            string st = string.Format("{0}\n{1}벽 : {2}개\t{3}바닥 : {4}", Name, WallName, Wall, FloorName, Floor);

           

            foreach (string str in others)

            {

                st += "\n" + str;

            }

            return st;

        }

Product(Element Class)에서는 생성할 복합 개체(건물)을 표현합니다. 슬립을 넣어서 건물이 만들어 지는 과정을 보여주면서 Builder 패턴을 느낄 수 있게 하였습니다.

 

interface StructureBuilder

    {

        Element CreateStructure();

    }

Builder(StructureBuilder Interface) 에서는 Product(건물) 개체의 일부 요소들을 생성하기 위한 인터페이스를 정의합니다.

 

class BuildingBuilder:StructureBuilder

    {

        #region StructureBuilder 멤버

        public Element CreateStructure()

        {

            Element element = new Element("빌딩");

            element.SetWall("시멘트"500);

            element.SetFloor("대리석"600);

            element.SetOthers("철근");

            element.SetOthers("벽돌");

            return element;

        }

        #endregion

    }

 

class HouseBuilder:StructureBuilder

    {

        #region StructureBuilder 멤버

        public Element CreateStructure()

        {

            Element element = new Element("집");

            element.SetWall("황토"100);

            element.SetFloor("온돌"50);

            element.SetOthers("기와");

            return element;

        }

        #endregion

    }

}

ConcreteBuilder(BuildingBuilder, HouseBuilder) 에서는 Builder(StructureBuilder)에 정의된 인터페이스를 구현하며, 건물의 재료들을 모아 빌더를 복합합니다.

 

class Architect

    {

        List<StructureBuilder> architect = new List<StructureBuilder>();

        public enum StructureType

        {

            BuildingType,

            HouseType

        }

        public Architect()

        {

            architect.Add(new BuildingBuilder());

            architect.Add(new HouseBuilder());

        }

 

        public Element Build(StructureType rt)

        {

            return architect[(int)rt].CreateStructure();

        }

    }

}

Director(Architect Class) 에서는 Builder 인터페이스를 사용하는 개체를 합성합니다. 소스를 보면 건축가가 Build 메서드로 오더받으면 빌딩, 집의 건설방법을 사용하여 해당 건물을 건축해서 반환하는 것을 알 수 있습니다.

 

class Program

    {

        static void Main(string[] args)

        {

            Architect architect = new Architect();

            Element element = architect.Build(Architect.StructureType.BuildingType);

            Console.WriteLine(element);

            element = architect.Build(Architect.StructureType.HouseType);

            Console.WriteLine(element);

        }

    }

Architect(건축가) 개체를 생성하여 개체안의 Build 메서드에 오더 할 건물의 타입을 넘겨주면 건축가는 건물을 건설해 줍니다.

 

결과 화면

 

'Programming > Design Pattern' 카테고리의 다른 글

[Design Pattern] Template Method  (0) 2015.04.16
[Design Pattern] Bridge Pattern  (0) 2015.04.16
[Design Pattern] Abstract Factory  (0) 2015.04.16
posted by Kanais
2015. 4. 16. 10:08 Programming/Design Pattern



참고 서적 : GOF의 디자인패턴 – Addison Wesley – 에릭감마, 리처드 헬름, 랄프 존슨, 존 블리시디스 지음. 김정아 옮김.


Abstract Factory란?

구체적인 클래스를 지정하지 않고 관련성을 갖는 객체들의 집합을 생성하거나 서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공하는 패턴입니다.

 

Abstract Factory의 구조



l  AbstractFactory : 개념적 제품에 대한 객체를 생성하는 연산으로 인터페이스를 정의합니다.

l  ConcreateFactory : 구체적인 제품에 대한 객체를 생성하는 연산을 구현합니다.

l  AbstractProduct : 개념적 제품 객체에 대한 인터페이스를 정의합니다.

l  ConcreateProduct : 구체적으로 팩토리가 생성할 객체를 정의하고, Abstract Factory가 정의하는 인터페이스를 구현합니다.

l  Client : AbstractFactory와 AbstractProduct클래스에 선언된 인터페이스를 사용 합니다.

ConcreateFactory가 자동차를 생산하는 공장이라고 한다면,

AbstractProduct는 자동차의 종류(소형차, 중형차 등)이고, Product는 자동차(티코,아반테 등)일 겁니다. 그리고 AbstractFactory는 자동차 회사라고 보시면 됩니다.

 


 

AbstractFactory의 활용성

-      객체가 생성되거나 구성 . 표현되는 방식과 무관하게 시스템을 독립적으로 만들고자 할 때

-      여러 제품군 중 하나를 선택해서 시스템을 설정해야 하고 한번 구성한 제품을 다른 것으로 대체할 수 있을 때

  (여기서 제품군이란 특정한 상황과 목적에 맞게 생성된 객체들의 집합을 말합니다. )

-      관련된 제품 객체들이 함께 사용되도록 설계되었고, 이 부분에 대한 제약이 외부에도 지켜지도록 하고 싶을 때

-      제품에 대한 클래스 라이브러리를 제공하고, 그들의 구현이 아닌 인터페이스를 노출시키고 싶을 때

 

Abstract Factory와 Factory Method 공통점

추상 클래스를 사용하여 제품을 생산해 낸다는 점이 공통점입니다.

 

Abstract Factory와 Factory Method 차이점

Abstract Factory? 
제품군을 만들기 위한 추상형식을 제공한다.
제품이 생성되는 방법은 서브클래스에서 정의된다
.
클라이언트에서 서로 연관된 일련의 제품을 만들어야 할때, 즉 제품군을 만들어야 할 때 사용한다. 


Factory Method?
클래스를 확장하고, 팩토리 메소드를 오버라이드한다.
팩토리메서드의 사용->서브클래스를 통해서 객체를 생성한다.

클라이언트와 구상 형식을 분리시켜주는 역할.
클라이언트 코드와 인스턴스를 만들어야 할 구상 클래스를 분리시켜야 할 때 활용한다. 어떤 구상 클래스를 필요로 하게 될지 미리 알 수 없는 경우에도 매우 유용하다.

 


 

Abstract Factory를 쓰는 이점과 부담

l  이점

1.    구체적인 클래스를 분리

추상 팩토리 패턴을 쓰면 응용프로그램이 생성할 객체의 클래스를 제어할 수 있습니다. 팩토리는 제품 객체를 생성하는 과정과 책임을 캡슐화한 것이기 때문에, 구체적인 구현 클래스가 사용자에게서 분리됩니다. 일반 프로그램은 추상 인터페이스를 통해서만 인스턴스를 조작합니다. 제품 클래스 이름이 구체 팩토리의 구현에서 분리되므로, 사용자 코드에는 나타나지 않는 것입니다.

 

2. 제품군을 쉽게 대체할 수 있다.

구체 팩토리의 클래스는 응용프로그램에서 한 번만 나타나기 때문에 응용프로그램이 사용할 구체 팩토리를 변경하기는 쉽습니다. 또한, 구체 팩토리를 변경함으로써 응용프로그램은 서로 다른 제품을 사용할 수 있게 변경됩니다. 추상 팩토리는 필요한 모든 것을 생성하기 때문에 전체 제품군은 한번에 변경이 가능합니다.

 

3. 제품 사이의 일관성을 증진

   - 하나의 군 안에 속한 제품 객체들이 함께 동작하도록 설계되어 있을 때, 응용프로그램은 한 번에 오직 한 군에서 만든 객체를 사용하도록 함으로써 프로그램의 일관성을 갖도록 해야 합니다. 추상 팩토리를 쓰면 이 점을 아주 쉽게 보장할 수 있습니다.

 

l  부담

새로운 종류의 제품을 제공하기 어려움

   - 새로운 종류의 제품을 만들기 위해 기존 추상 팩토리를 확장하기가 쉽지 않습니다. 생성되는 제품은 추상 팩토리가 생성할 수 있는 제품 집합에만 고정되어 있기 때문입니다. 만약 새로운 종류의 제품이 등장하면 팩토리의 구현을 변경해야 합니다. 이는 추상 팩토리와 모든 서브클래스의 변경을 가져옵니다. 즉, 인터페이스가 변경되는 새로운 제품을 생성하는 연산이 추가되거나, 기존 연산의 반환 객체 타입이 변경되었으므로, 이를 상속받는 서브클래스 모두 변경되어야 합니다.


 

Abstract Factory구현 기법

 

1.    팩토리를 단일체(Singleton)로 정의

   - 전형적으로 응용프로그램은 한 제품군에 대해서 하나의 ConcreateFactory인스턴스만 있으면 됩니다. 즉, 갖가지 제품의 종류를 만들어 내는 팩토리는 제품군에 대해서 하나면 되는 것입니다. 그러므로 단일체로 구현하는 것이 바람직합니다.

 

2. 제품을 생성

   - AbstractFactory는 단지 제품을 생성하기 위한 인터페이스를 선언하는 것이고, 그것을 생성하는 책임은 Product의 서브클래스인 ConcreateProduct에 있습니다. 이를 위한 가장 공통적인 방법은 각 제품을 위해서 팩토리 메서드를 정의하는 것입니다. AbstractFactory는 각 제품 생성을 위한 팩토리 메서드를 재정의함으로써 각 제품의 인스턴스를 만듭니다. 이 구현은 간단하지만, 제품군이 약간 다르다면 각 제품군을 위한 새로운 구체 팩토리 서브클래스가 필요합니다.

 

3. 확장 가능한 팩토리들을 정의

   - AbstractFactory에는 생성할 각 제품의 종류별로 서로 다른 연산을 정의합니다. 이 제품들의 종류는 연산 시그니처를 보면 알 수 있습니다. CreateProductA를 통해 ProductA를 만듭니다. 새로운 종류의 제품이 추가되면 AbstractFactory의 인터페이스에도 새로운 연산을 추가해야 합니다. 좀더 유연하게 하려면 생성할 객체를 매개변수로 만들어 연산에 넘기면 됩니다. 그리고 매개변수에다가 생성할 객체의 종류를 표현합니다.


 

예제 프로그램

 



  디자인

클래스 명

역할

CarFactory

AbstractFactory에 해당하는 클래스.

MUFactory

DogCar와 SoccerCar를 생성함.

TSFactory

CatCar와 BaseballCar를 생성함.

MiniCar

DogCar와 CatCar의 공통된 함수를 선언.

DogCar

MiniCar의 함수를 재정의 함.

CatCar

MiniCar의 함수를 재정의 함.

SportsCar

SoccerCar와 BaseballCar의 공통된 함수를 선언.

SoccerCar

SportsCar의 함수를 재정의 함.

BaseballCar

SportsCar의 함수를 재정의 함.

 

 

 


 

  CarFactory 클래스와 CarFactory클래스에서 파생된 MUFactory클래스와 TSFactory클래스

 



 

l CarFactory 멤버필드

멤버필드 명

설 명

Minicars

Minicar를 보관하는 벡터

sportscars

sportscar를 보관하는 벡터

 

l CarFactory 멤버 메서드

메서드 명

설 명

.ctor(void)

기본 생성자

CreateMiniCar

MiniCar타입의 개체를 생성 하는 가상함수.

CreateSportsCar

SportsCar타입의 개체를 생성 하는 가상함수.

DisposeMiniCar

매개변수로 받은 MiniCar개체를 벡터에서 삭제한다.

DisposeSportsCar

매개변수로 받은 SportsCar개체를 벡터에서 삭제한다.

PushMiniCar

MiniCar개체를 벡터에 삽입한다.

PushSportsCar

SportsCar개체를 벡터에 삽입한다.

DisposeMiniCar

MiniCar개체가 벡터에 있다면 KillMiniCar실행

DisposeSportsCar

SportsCar개체가 벡터에 있다면 KillSportsCar 실행

KillMiniCar

MiniCar개체를 삭제한다.

KillSportsCar

SportsCar개체를 삭제한다.

 

CarFactory::CarFactory(void)

{

}

 

CarFactory::~CarFactory(void)

{

        DisposeMiniCars();

        DisposeSportsCars();

}

 

void CarFactory::PushMiniCar(MiniCar *minicar)

{

        minicars.push_back(minicar);

}

void CarFactory::PushSportsCar(SportsCar *sportscar)

{

        sportscars.push_back(sportscar);

}

bool CarFactory::DisposeMiniCar(MiniCar *minicar)

{

        miter seek = find(minicars.begin(),minicars.end(),minicar);

        if(seek != minicars.end())

        {

               minicars.erase(seek);

               delete minicar;

               return true;

        }

        return false;

}

bool CarFactory::DisposeSportsCar(SportsCar *sportscar)

{

        siter seek = find(sportscars.begin(),sportscars.end(),sportscar);

        if(seek != sportscars.end())

        {

               sportscars.erase(seek);

               delete sportscar;

               return true;

        }

        return false

}

 

void CarFactory::DisposeMiniCars()

{

        find_if(minicars.begin(),minicars.end(),KillMiniCar);

 

}

void CarFactory::DisposeSportsCars()

{

        find_if(sportscars.begin(),sportscars.end(),KillSportsCar);

}

 

bool CarFactory::KillMiniCar(MiniCar *minicar)

{

        delete minicar;

        return false;

}

bool CarFactory::KillSportsCar(SportsCar *sportscar)

{

        delete sportscar;

        return false;

}

 

CarFactory클래스의 CreateMiniCar메서드와 CreateSportsCar메서드를 MUFactory와 TSFactory에서 재정의해서 사용하고 있다. 하지만 MUFactory클래스에서 만들어진 MiniCar타입의 개체와 TSFactory클래스에서 만들어진 MiniCar타입의 개체는 다른 개체이다.

Client가 어느 Factory에 주문을 하느냐에 따라서 생산되는 Car는 다를 것이다. MUFactory에 주문을 한다면 DogCar가 생산되고, TSFactory에 주문을 한다면 CatCar가 생산될 것이다.

 

 

  MiniCar클래스와 MiniCar클래스에서 파생된

CatCar클래스 와 DogCar클래스

 



 

메서드 명

설 명

Smaile

클래스에 따라 다른 문자열이 출력된다.

 


 

  SportsCar클래스와 SportsCar로부터 파생된 SoccerCar클래스와 BaseballCar클래스

 



 

메서드 명

설 명

Playball

클래스에 따라 다른 문자열이 출력된다.



'Programming > Design Pattern' 카테고리의 다른 글

[Design Pattern] Template Method  (0) 2015.04.16
[Design Pattern] Bridge Pattern  (0) 2015.04.16
[Design Pattern] Builder  (0) 2015.04.16
posted by Kanais
2015. 4. 16. 10:06 Programming/Android

Android 설치

목차

JDK 설치

JDK 환경 설정

Eclipse 설치

Android SDK 설치

ADT Plug-in 설치

Android Virtual Device(AVD) 설치

 

Android 설치 방법

JDK 설치

JDK 다운로드

www.oracle.com/technetwork/java/index.html 에 접속해서 Java SE를 클릭합니다.


그리고 다음 페이지에서 Download JDK 를 클릭합니다.

 

자신의 컴퓨터 OS에 따라 다운로드를 클릭합니다.

 


다운로드한 후

 

실행을 눌러 설치를 합니다.

 

 


Account 등록

 


JDK 환경 설정

제어판에서 시스템을 더블 클릭합니다.

 

 

시스템 등록 정보에서 고급 탭을 선택 후 환경 변수 클릭.

 

l  환경 변수에서 새로 만들기를 클릭 합니다.

l  그리고 변수 이름에 CLASSPATH를 입력하고, 변수 값에 jdk가 있는 폴더를 설정하기 위해 .;C:\Program Files\Java\jdk1.6.0_25\bin을 입력합니다.

l  그리고 확인 버튼을 클릭합니다.


이렇게 환경변수를 설정 해도 안된다면, 다음과 같이 해보세요.


사용자 변수 중 path 에서 C:\Program Files\Java\jdk1.6.0_25\bin 을 추가하고 lib에는 C:\Program Files\Java\jdk1.6.0_25\lib 를, include에는 C:\Program Files\Java\jdk1.6.0_25\include 를 추가해 보세요. 
  그리고 시스템 변수에서 
새로 만들기를 클릭 후 javaw(이름은 아무거나 설정하셔도 되요) 로 변수 이름을 설정하시고요 변수 값으로 C:\Program Files\Java\jre6\bin을 추가시켜 주세요

그리고 path에 ;%javaw%\bin;(세미콜론(;)은 앞 문장과 구별하기 위해 앞에 꼭 붙여 줘야 합니다.)를 추가시켜주세요.

그러고도 안된다! 그러면 재부팅을 한번 해보세요.

 

Eclipse 설치

http://www.eclipse.org 에서 다운받을 수 있습니다.

 

Eclipse IDE for Java EE Developers 를 설치하여도 상관없지만, 교육용으로 사용하려 한다면 Galileo Package를 설치해도 무관합니다.




압축을 푼 후 eclipse 폴더를 원하는 곳에 두면 됩니다. 그러나 작업 환경을 위해 별도의 폴더를 지정해서 설치해주는 편이 좋습니다.

 

 



Eclipse 초기 화면

 


Android SDK 
설치

Android SDK 다운로드

먼저 http:// http://developer.android.com/sdk/index.html 홈페이지 접속하시고

사용하고 계시는 컴퓨터 OS 에 맞게 package 를 다운로드 해주세요

 

다운로드 받은 파일을 압축을 풀어서 Android 폴더 안에 넣어 주세요.

 


ADT Plug-in 
설치

l  ADT Plug-in for Eclipse

Eclipse  Help메뉴에서 Install New Software를 클릭하세요

 

 

그리고 Add 버튼을 클릭해서 Name에는 Android plugin을 입력하시고, Location에는 http://dl-ssl.google.com/android/eclipse/ 를 입력하고 OK 버튼을 클릭 해주세요.

 

 

 

 

install을 하다 보면 Warning 창이 뜹니다. OK 버튼을 클릭해 주시고요, Needed에서도 OK 클릭 Updates에서는 yes를 클릭해 주세요

 


Android SDK 
폴더 등록

Eclipse  Window메뉴에서 Preferences 를 클릭 하세요.

 

 

그리고 Browse를 클릭해서 SDK가 설치되어 있는 폴더를 선택 후 확인 버튼을 클릭해 주세요

 


그리고 Apply를 클릭 후 OK 버튼을 눌러 주세요

 


Eclipse  Window 
메뉴에서 Android SDK and AVD Manager를 클릭하세요

 

Installed packages를 클릭해서 SDK가 있는지 확인해 주시고

 


Available pacakage
를 클릭 하여 Android Repository 에서 설치할 SDK를 선택 후에 Install Selected 를 클릭 하세요.

 


그리고 Accept를 클릭한 후 Install을 클릭하시면 Plug-in이 설치 됩니다.

다만.. Plug-in 설치시 설치할 SDK가 많다면 그만큼 시간이 오래 걸립니다 ^^; 그점 유의해 주세요.

 

 설치가 완료가 되면 Close를 누르시면 됩니다.

 


Android Virtual Device 
설치

안드로이드폰 에뮬레이터 설정

 

 


Name
을 입력하시고 Target을 선택 후 Create AVD 버튼을 클릭해 주세요

 


그리고 AVD 생성 완료 확인하면 끝입니다.

 



이것으로 안드로이드 설치가 끝입니다.

posted by Kanais