추상 팩토리 패턴 Javascript 의 디자인 패턴 중 하나로서, 말 그대로 객체를 추상화 하여 공장처럼 찍어내는 패턴이라는 의미이다. ECMA 5 이후 부터는 Class에 대한 개념이 생겨 Java와 비슷하게 사용할 수 있지만, 여기에서 설명하는 추상 팩토리 패턴은 prototype을 기준으로 설명한다.
추상 팩토리 패턴을 보며 가장 많이 나오는 예제가 왕과 왕국에 대한 예제가 많이 나온다. 이 글에서는 좀 더 쉽게 설명하기 위해 통장 입/출금을 예시로 든다. 일단 계좌에 대한 기능으로는 기본적으로 사용해야할 입금과 출금 의 기능이 있을 것이다. 그리고 그 기능을 각 은행 별로 해당 기능을 공유할 것이다. 먼저 계좌에 대한 기능을 구현해보겠다.
1 2 3 4 5 6 7 8 9 10 11 var AccountFactory = ( function ( ) { var personalAccount = null ; return { deposit: function ( ) { }, withdraw: function ( ) { } } })();
빌더 패턴 Wiki 백과에 따르면 빌더 패턴이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다
라고 정의하고 있다. 빌더 패턴은 생성자 인자로 너무 많은 인자가 넘겨지는 경우, 그 인자가 어떤 값인지 파악하기 힘들어, 그에 따라 매개 변수를 받아 한번에 처리할 수 있도록 하기 위해 고안해낸 패턴이라고 한다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class SetCharacter { private userId: string; private level: number; private gender: string; constructor (userId: string, level: number, gender: string) { this .userId = userId; this .level = level; this .gender = gender; } getUserId(): string { return this .userId; } getLevel(): number { return this .level; } getGender(): string { return this .gender; } } let martin = new SetCharacter('martin' , 30 , 'man' );var SetCharacter = (function ( ) { function SetCharacter (userId, level, gender ) { this .userId = userId; this .level = level; this .gender = gender; } SetCharacter.prototype.getUserId = function ( ) { return this .userId; }; SetCharacter.prototype.getLevel = function ( ) { return this .level; }; SetCharacter.prototype.getGender = function ( ) { return this .gender; }; return SetCharacter; }()); var martin = new SetCharacter('martin' , 30 , 'man' );
위의 Class의 경우에는 케릭터를 생성하는 함수가 있다. 그 함수에는 인자로 해서 ‘이름, 나이, 성별’ 을 차례대로 집어넣게 되어있는데, 만약 특정 데이터가 없거나 혹은 개발자의 실수로 인자의 순서를 잘 못 넣은 경우의 사이드 이펙트는 걷잡을 수 없을 것이다. 이러한 단점을 보완할 수 있는 것이 빌더 패턴이다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 class Character { private userName: string; private gender: number; private phoneNumber: string; private userId: string; private job: string; private grade: string; constructor (builder) { this .userName = builder.userName; this .gender = builder.gender; this .phoneNumber = builder.phoneNumber; this .userId = builder.userId; this .job = builder.job; this .grade = builder.grade; } static createCharacter(userName, gender, phoneNumber ) { return new CharacterBuilder(userName, gender, phoneNumber); } } class CharacterBuilder { private userName: string; private gender: string; private phoneNumber: number; private userId: string; private job: string; private grade: string; constructor (userName, gender, phoneNumber) { this .userName = userName; this .gender = gender; this .phoneNumber = phoneNumber; } setUserId(userId): object { this .userId = userId; return this ; } setGrade(grade): object { this .grade = grade; return this ; } setJob(job): object { this .job = job; return this ; } build() { return new Character(this ); } } var createCharacter = Character.createCharacter('김영훈' , '01012345678' , 'man' );var martin = createCharacter.setUserId('martin' ).build();
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 32 33 34 35 36 37 38 39 var Character = (function ( ) { function Character (builder ) { this .userName = builder.userName; this .gender = builder.gender; this .phoneNumber = builder.phoneNumber; this .userId = builder.userId; this .job = builder.job; this .grade = builder.grade; } Character.createCharacter = function (userName, gender, phoneNumber ) { return new CharacterBuilder(userName, gender, phoneNumber); }; return Character; }()); var CharacterBuilder = (function ( ) { function CharacterBuilder (userName, gender, phoneNumber ) { this .userName = userName; this .gender = gender; this .phoneNumber = phoneNumber; } CharacterBuilder.prototype.setUserId = function (userId ) { this .userId = userId; return this ; }; CharacterBuilder.prototype.setGrade = function (grade ) { this .grade = grade; return this ; }; CharacterBuilder.prototype.setJob = function (job ) { this .job = job; return this ; }; CharacterBuilder.prototype.build = function ( ) { return new Character(this ); }; return CharacterBuilder; }()); var createCharacter = Character.createCharacter('김영훈' , '01012345678' , 'man' );var martin = createCharacter.setUserId('martin' ).build();
팩토리 메소드 단일체 프로토타입 출처 http://asfirstalways.tistory.com/350 http://using.tistory.com/71 http://leetaehoon.tistory.com/57 http://jays1204.github.io/pattern/2015/11/09/builder-pattern.html http://jdm.kr/blog/217 https://www.zerocho.com/category/JavaScript/post/57bab0ee5abe0c17006fe22f
현재 이커머스회사에서 frontend 개발자로 업무를 진행하고 있는
Martin 입니다. 글을 읽으시고 궁금한 점은 댓글 혹은 메일(hoons0131@gmail.com)로 연락해주시면 빠른 회신 드리도록 하겠습니다. 이 외에도 네트워킹에 대해서는 언제나 환영입니다.:Martin(
https://github.com/martinYounghoonKim )