2018년 4월 23일 월요일

Creational Pattern


Creational Pattern 에 대한 썰

byHAJUNHOApr 18. 2018

0. 시작

400 구독자가 보셨던 내 지난 글은 실무프로그래밍 기초편을 위한 글이고, 이 글부터는 중급편이라 자세한 설명은 생략한다. 코드도 책에만 실리지 딱히 공개 안 한다. 같은 회사에서 패턴 강의 들은 친구들이 유출하면 모르겠지만 ㅠㅠ 그리고 존댓말이 아니라 반말임. 만나면 존댓말 쓸거니 글에서는 이해해 주3. 최근 안드로이드와 iOS 파트를 후임들에게 물려주고 있다. 안드로이드 플랫폼 자체가 패턴 덩어리. 그리고 많은 디자인 패턴이 적용된 어플을 주고 있다. 당최 인터넷 찾아봐도 패턴을 잘 모르겠다는 후임들을 위해 세미나를 하고 있는데 작은 몇 마디 만으로도 Creational Pattern을 이해하는 것을 보고 실무 프로그래밍 중급편에 실릴 내용으로 세미나를 하여 여기도 적어 본다. 우선 "썰"이라 붙인 이유는 자세한 설명은 인터넷에 많으니 그들의 연결 개념을 전체적으로 말해두려고 한다. 열심히 공부하다 보면 이 글의 말로 Creational 패턴을 모두 연결할 수 있을 것이다.

1. 패턴 공부는 시작은 자바로

우선, 패턴은 자바 기준으로 공부하는 게 맞다. JAVA와 C#은 실무 프로그래밍을 한 입장 + 문법 관점에서 완전히 동일한 언어로 봐도 된다. C++도 마찬가지겠지만 그렇게 보면 안 되겠다. class 가 메소드(펑션, 함수)를 포함한다는 것을 빼면 struct랑 완전히 동일 개념이지만 다르다고 생각해야 하듯이 C++은 다른 언어로 봐야 한다. 물론, 공부할 때 생각만 다르다고 하는 것이지. C/C++, JAVA, C#, SWIFT에 적용되는 패턴은 완전히 동일하다. C/C++ 만 한 친구들에게 자바를 이해시키고 예제 코드를 짜게 하는데 딱 하루 걸렸다. 그다음 날은 전혀 스트레스 없이 완전하게 자바 코드를 짜고 자바 기반의 안드로이드 프로그램을 수정하기 시작했다. 그러나 자바 기준으로 이야기를 하는 것에 대해서는 이해를 하기 바란다.

2. 패턴을 만든 이유

진심은 이 글 제일 마지막에 적었다. 그러나 표면적 이론을 따지자면, 생성 패턴은 코드수를 줄이기 위해 만들었다. 코드수를 줄이는 방법은 재사용성을 높이는 것이고, 재 사용성을 높이려면 작은 조각으로 나누되 설계를 잘해서 만들어야 한다. 코드수가 많아지더라도 요구사항에 대해 더욱 유연하게 대응해서 개발 시작부터 Acceptance Test를 할 기간을 더 줄일 수 있다면, 그것은 패턴이 잘 적용된 것이다. 패턴 공부는 따로 안 해도 된다. 안드로이드 프로그래밍을 하면 된다. 거기 모든 패턴이 녹아 있다. 그래서 안드로이드 프로그래밍 한 달만 하고 이 글을 보면 바로 모든 게 이해될 것이다.

3. 한방에 설명

자바에서 메모리에 뭔가를 생성시키는 것은 딱 3가지밖에 없다. new, static, primitive type. 그러나 기본 자료형은 빼야 한다.(너무 당연한 것이고 기본자료형으로만 통신하는 프로토콜을 만들 때(안드로이드의 AIDL 같은)만 필요해서 빼는 것이다) 결국 2가지인데, Creational Pattern은 애들은 어떻게 쓰느냐에 따라 다른 것이다.
결국 static와 new를 어떻게 쓸 것이냐.

지워졌었던 내 글을 봤다면 다형성은 void 포인터로 for문을 돌리기 위해 만든 개념이고 캡슐화는 개발자를 믿지 못하기 때문에 만든 개념이라고 이해했을 것이다. 

싱글톤 패턴은 

생성자를 캡슐화하고 하나만 생성되게 하는 것이다. private으로 생성만 만들면 결국 캡슐화를 통해 매소드를 통해서 전달할 수밖에 없는데 하나만 전달하게 하면 싱글톤 패턴이 되는 것이다.

    public static synchronized GlobalSetting getInstance() {
        if (mInstance == null) {
            synchronized (java.lang.Object.class) {
                if (mInstance == null)
                    mInstance = new GlobalSetting();
            }
        }
        return mInstance;
    }

이런 녀석은 예제의 이름처럼 세팅값을 저장하고 여러 클래스에서 불러 쓸 때 매우 유용한다.

팩토리 매소드도 비슷한 녀석이다.


public FactoryMethodModel() {
ARM samsung = makeInstance();
ARM nvidia = makeInstance();
ARM qualcomm = makeInstance();

직접 NEW를 하지 않는 점에서.
다른 클래스에서 생성해서 리턴해 주도록 만들면 된다.

class SAMSUNGEngineer extends FactoryMethodModel {
@Override
protected ARM makeInstance() {
return new ARM("samsungARM");
}
}

문제는 왜 이렇게 만들까? 
final List<ARM> armlist = new ArrayList<>();
리스트를 만들 수 있기 때문이다.
armlist.add(samsung);
이렇게 추가하기 위해서다.

자바의 abstract는 interface와 똑같은 녀석인데 멤버 자료형을 가질 수 있다는 점에서 차이가 있다. 자바 용어로 말하면, 멤버 변수인데 별로 마음에 안 든다. 여하튼, 그것을 이용한다.

얘는 어디에 쓸까? 안드로이드의 BR 서비스랑 비슷한 것을 만든다고 하자. 그럼 앱 규격을 내려주고 하위에서 구현해서 위로 올려주고 나는 목록만 가지고 있으면 알림이 왔을 때 리스트에 대고 for를 돌리면 그게 BroadCast 가 된다. 해당 앱.수행할 메소드() 를 적어주면 메시지 구조나 이벤트 드리븐 기능을 구현할 수 있다.

템플릿 메소드는

사실상 팩토리 매소드와 같다. new 를 하는 주체가 연결 클래스에 있으니 말이다. 템플릿은 interface를 하나 더 두어서 연결 클레스가 구현해야할 메소드의 명세를 명시화 한다는 개념이 추가 되어 사실상 더 큰 개념이다. 인터넷에 이론가들은 절대 동의하지 않는 것 같지만 뭔 프로그램을 만들었는지 알게 뭐람. 컴파일러 만들 때도 실무 경험 없는 이론가들이 만드는 개념은 무쓸.

빌더 패턴은 

new 할 때 멤버변수를 미리 세팅하고자 하기 위해 만들었다. 그냥 생성자를 오버로딩 해서 쓰는게 LOC(Line Of Code)가 더 줄지 않느냐고 묻는다면 어느 정도 수준에서는 빌더 패턴이 더 낫다고 말하고 싶다. 그게 어느 수준이냐?
Chip c = Builder.setBrand("SAMSUNG").setPrice("개비쌈").build();
로 나갈 때 setPrice가 int면 모르겠는데 저렇게 String을 적는다면 setPirce만 오버로딩 하면 되는데 생성자의 경우 경우의 수가 더 많아진다.
그럼 저렇게 . 찍는 것은 어떻게 구현하냐?
        this.brand = brand;
        return this;
return 을 클래스 자체로 리턴하면 계속 . 을 찍을 수 있다. 이론 관점이 아니 코드 관점에서 먼저 보면 참 쉽다.

Strategy 패턴은

인터페이스를 나누는 기술이다. 
라는 것만 알고 인터넷 서핑 공부법(실무프로그래밍 참고)으로 공부하면 된다.

Prototype 패턴은

interface, Abtract, class를 얼마나 예쁘게 만드는지에 대한 연구이다. 사실 팩토리 메소드 패턴인데 객체 생성 이름은 clone()으로 한 것 뿐. clone() 안에 super.clone() 이 있던 말던 최종 clone에는 static 혹은 new가 들어갈 수밖에 없다. 

이 모든 패턴을 조합해서 만든 Creational 패턴이 바로 

Abstract Factory Pattern이다.

Factory Method처럼 바로 하위에서 바로 객체를 생성해서 리턴해 주는 게 아니라 우선 Factory를 받아오고 해당 Factory를 이용해서 new(creation)를 한다. 이렇게 설계하는 과정 자체에 protytype과 stategy 패턴이 들어가고 팩토리에서 실제 객체를 생성하는 패턴은 Factory Method다. 해당 팩토리가 부르는 클래스 안에는 세팅 다 해서 자기 객체 리턴하는 하는데, 생성자가 복잡해진다 싶으면 빌더 패턴으로 구현하는 것이 편하다.


내가 패턴을 공부하게 되었던 것도 학창 시절 교수님께서 구입해 주셨던 GoF Design Pattern 때문인데. 사실 코드로 보다 보니 거기 써져있던 패턴 맵이 그 책의 정수라는 것을 알게 되었다.

권장하는 것은 아니지만 워낙 유명한 책은 인터넷에 항상 PDF로 있으니
gof design pattern filetype:pdf
으로 잘 찾으시고 책이 좋으면 꼭 원서를 구입하시기 바란다.

4. 결론

creational pattern 은 new를 어디서 할지 정하는 패턴.
즉,
new pattern 으로 불러야 한다. 너무 싼티나면

memory allocation pattern.

스타트업 이야기

혹은,
I can't trust you pattern. 사실 패턴이란 것은 협업 시 다른 사람에게 인터페이스, Abstract, Protocol, Specification Documents(스펙) 던져주고 전체 그림을 못 보게 만들려는 수작이다. 전체 소스는 주되 쉽게 접근할 핵심은 말 안하다는(언젠가는 분석된다면 시간이 필요하지)  나 혼자 성공하려면 넌 좀 모르게 할 필요가 있을 때 쓰니까 그런 정치에 맞서 사용자가 원하는 프로그램을 만들고 싶을 때, 패턴을 잘 배워두자.

댓글 없음:

댓글 쓰기

국정원의 댓글 공작을 지탄합니다.

bootcamp 지우기

맥북 프로 레티나 터치바 diskutility 에서 bootcamp 파티션 삭제하면 검은색에서 회색으로 바뀐다(APFS로 지정) 파틴션 아이콘 클릭하여 - 버튼을 이용하여 삭제하면 끝.