[javascript] Class vs Factory 함수 비교

in kr •  7 years ago 



Class vs Factory

class는 ES6(ECMAScript 2015)에서 추가된 문법으로, class 함수 와 factory 함수를 비교해 보려 합니다.

  • class
class TodoModel {
    constructor(){
        this.todos = [];
        this.lastChange = null;
    }
    
    addToPrivateList(){
        console.log("addToPrivateList"); 
    }
    add() { console.log("add"); }
    reload(){}
}
  • factory function
function TodoModel(){
    var todos = [];
    var lastChange = null;
        
    function addToPrivateList(){
        console.log("addToPrivateList"); 
    }
    function add() { console.log("add"); }
    function reload(){}
    
    return Object.freeze({
        add,
        reload
    });
}

캡슐화(Encapsulation)

내부 변수, 감추고싶은 함수에 접근 가능한지 여부를 확인

  • class : 접근 가능
var todoModel = new TodoModel();
console.log(todoModel.todos);     //[]
console.log(todoModel.lastChange) //null
todoModel.addToPrivateList();     //addToPrivateList
  • factory : 접근 불가
var todoModel = TodoModel();
console.log(todoModel.todos);     //undefined
console.log(todoModel.lastChange) //undefined
todoModel.addToPrivateList();     //taskModel.addToPrivateList is not a function

불변성(Immutable API)

한번 정의된 기능(함수)은 변경되지 않아야 됩니다.

  • class : 함수 변경 가능
todoModel.reload = function() { console.log("a new reload"); }
todoModel.reload();            //a new reload
  • factory : 함수 변경 불가
todoModel.reload = function() { console.log("a new reload"); }
todoModel.reload();            //reload

new

factory 함수를 사용하여 객체를 만들 때 new는 필요하지 않지만 더 읽기 쉽도록 만들면 갈 수 있습니다. 아무런 해가 없습니다.

  • factory : new 키워드를 사용해도 무방함(사용해도 되고, 안해도 되고)
var todoModel= new TodoModel();

상속(inheritance)

  • class : extends 키워드를 통해 class 정의를 상속받을 수 있음
class Service {
  doSomething(){ console.log("doSomething"); }
}
class SpecialService extends Service {
  doSomethingElse(){ console.log("doSomethingElse"); }  
}
var specialService = new SpecialService();
specialService.doSomething();
specialService.doSomethingElse();
  • class : java 에서 interface를 구현하는 것처럼 외부 파라미터를 통해 injection 받아 구현
class Service {
  doSomething(){ console.log("doSomething"); }
}
class SpecialService{
  constructor(args){
    this.service = args.service;
  }
  doSomething() { this.service.doSomething(); } 
  
  doSomethingElse(){ console.log("doSomethingElse"); }
}
var specialService = new SpecialService({
   service : new Service()
});
specialService.doSomething();
specialService.doSomethingElse();
  • function : class에서 2번째 구현한 방식으로 처리
function Service() {
  function doSomething(){ console.log("doSomething"); }
  return Object.freeze({
    doSomething
  });
}
function SpecialService(args){
  var service = args.service;
  function doSomethingElse(){ console.log("doSomethingElse"); }
  return Object.freeze({
    doSomething : service.doSomething,
    doSomethingElse
  });
}
var specialService = SpecialService({
   service : Service()
});
specialService.doSomething();
specialService.doSomethingElse();

메모리

메모리 소비에 있어서 class 방식이 factory 보다 우수함.

클래스는 프로토 타입 시스템을 통해 구현되므로 메모리 절약 기능이 뛰어납니다. 모든 메소드는 프로토 타입 객체에서 한 번만 생성되며 모든 인스턴스에서 공유됩니다.

하지만 수천 개의 동일한 객체를 만들 때 factory 함수의 메모리 비용이 많이 드는 것을 볼 수 있습니다.

메모리 사용량 (in Chrome)

개체10회 호출20회 호출
1000
1000.1Mb0.1Mb
10000.7Mb1.4Mb
100007.3Mb14.2Mb

결론

factory 형태를 사용하자 !

클래스의 강점은 익숙한 문법(java)과 메모리 사용에 있어 우위를 점하지만, 함수 재정의 및 this를 통한 내부 변수 접근 등은 보안등에 취약하다는 것에 주의 해야 할 것입니다.

물론, 예외적으로 React의 경우처럼 구성 요소의 프레임 워크에서 필요한 경우 클래스가 사용됩니다.

팩토리 함수는 보안되고 캡슐화 된 유연한 OOP 객체를 만드는 데 있어 더 좋은 선택일 뿐만 아니라 자바 스크립트 프로그래밍 패러다임에 새로운 문을 열어줍니다.

참조

: https://medium.freecodecamp.org/class-vs-factory-function-exploring-the-way-forward-73258b6a8d15


이전 관련 글은 #w-js 태그를 통해 확인하실 수 있습니다.
오늘도 행복한 하루 되세요 from @wonsama
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Class vs Factory 함수 비교 Class vs Factory class 관련내용 잘봤네요. 멋있습니다.

응원 감사합니다 ^^

와우... 예시와 함께 ㅠㅠ 너무 좋군요~~
좋은 내용 잘봤습니다..!!
팩토리를 써서 보안에 뛰어나도록 개발해야겠군요..!!

ES6 공부도 게을리하고... 크롬익스텐션 개발도 게을리하고...
요즘 배그덕분에 다 게을리하고 있네요.. ㅎㅎ

오늘도 치킨이닭 !!

pairplay 가 kr-dev 컨텐츠를 응원합니다! :)