ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 모듈 정의패턴
    @19.1 ~ /Nodejs 2020. 6. 3. 00:42

    1. exports 지정하기

    public API를 공개하는 가장 기본적인 방법은 export로 명기하는 것입니다

    이것은 exports에서 참조하는 객체의 속성에 공개할 모든 값을 할당하는 것입니다

    이렇게 하면 외부에 공개된 객체가 일련의 관련 기능들에 대한 컨테이너 또는 네임스페이스가 됩니다

    //logger.js
    exports.info = (message)=>{
    	console.log('info:' + message);
    };
    
    exports.verbose = (message) =>{
    	console.log('verbose:' + message);
    };
    
    
    //아래처럼 사용이 가능하다
    
    const logger = require('./logger');
    logger.info('this is time');
    logger.verbose('verbose message');

    대부분의 코어모듈은 이 패턴을 사용한다

    따라서 exports로 지정하는것이 CommonJS의 명세와 호환되는 유일한 방식입니다

     

    다음에 보는것들은 이것의 확장기능입니다

     

    2. 함수 내보내기

    가장 일반적인 모듈 정의 패턴 중 하나가 module.exports 변수 전체를 함수에 재할당하는것입니다

    주요 장점은 모듈에 대한

    명확한 진입점을 제공하는 단일 기능을 제공하여 그것에 대한 이해와 사용을 단순화한다는 것입니다

    //logger.js
    module.exports = (message) => {
    	console.log(`info:${message}`);
    };
    
    //익스포트된 함수를 네임스페이스로 사용해서 앞에 정의한 모듈을 어떻게 확장할 수 있는지를 보여줍니다
    moudle.exports.verbose = (message) =>{
    console.log(`verbose:${message}`);
    }
    
    
    const logger = require('./logger');
    logger('message');
    logger.verbose('message');

    단순히 함수를 내보내는 것이 제약 처럼 보일 수도 있지만 실제로는 단일 기능에 중점을 두도록하는 완벽한 방법입니다

     

    3. 생성자 익스포트하기

    생성자를 익스포트하는 모듈은 함수를 내보내는 모듈이 특화된것 입니다

    차이점은 이 새로운 패턴을 통해 사용자에게 생성자를 사용하여 새 인스턴스를 만들 수 있게 하면서 

    프로토 타입을 확장하고 새로운 클래스를 만들 수 있는 기능도 제공할 수 있다는 것입니다

    //logger.js
    function Logger(name){
    	this.name = name;
    }
    
    Logger.prototype.log = function(message){
    	console.log(`[${this.name}]${message}`);
    }
    
    Logger.prototype.info = function(message){
    	this.log(`info:{message}`);
    }
    
    Logger.prototype.verbose = function(message){
    	this.log(`verbose:${message}`);
    }
    
    module.exports = Logger;
    
    
    
    
    //사용시
    const Logger = require('./logger');
    
    const dbLogger = new Logger('DB');
    dbLogger.info('message');
    
    const accessLogger= new Logger('ACCESS');
    accessLogger.verbose('message');

     

    ES2015 클래스를 익스포트 할 경우

    class Logger
    {
    	constructor(name){
        	this.name = name;
        }
        
        log(message){
        	console.log(`[${this.name}]${message}`);
        }
        
        info(message){
        	this.log(`info : ${message});
        }
        
        verbose(message){
        	this.log(`verbose : ${message});
        }
    }
    
    module.exports = Logger;

     

    여전히 모듈에 대한 단일 진입점을 제공하지만 2번과 비교했을때 더 많은 모듈의 내부를 노출합니다

    그러나 기능 확장에 있어 훨씬 더 강력할 수 있습니다

    이 패턴의 변형은 new 명령을 사용하지 않는 호출에 대해 보호를 적용하는것으로 팩토리로 사용할 수 있다

    //this가 존재하는지 그것이 Logger의 인스턴스인지
    //거짓인 경우 이것은 new를 사용하지않고 Logger()함수를 바로 호출한 것을 의미(실수로 Logger()했을경우)
    //새 인스턴스를 올바르게 생성한 후 호출자에게 반환합니다
    function Logger(name){
    	if(!(this instanceof Logger)){
        	return new Logger(name);
        }
        this.name = name;
    }
    
    
    //ES2015의 new.target사용시
    function Logger(name){
    	if(!new.target){
        	return new Logger(name);
        }
        this.name = name;
    }
    
    
    const Logger = require('./logger');
    const dbLogger = Logger('DB'); //이 경우가 new를 사용하지 않고 Logger()함수를 호출한경우
    dbLogger.verbose('message');

     

    4. 인스턴스 익스포트 하기

    require()함수는 캐싱 메커니즘을 이용하여 생성자나 팩토리를 통해 모듈을 생성하므로 서로 다른 모듈간에 공유할 수 있는 상태저장(stateful) 인스턴스를 쉽게 정의할 수 있습니다

    //logger.js
    function Logger(name){
    	this.count = 0;
        this.name = name;
    }
    
    Logger.prototype.log = function(message){
    	this.count++;
        console.log('['+this.name+']' + message);
    };
    
    //인스턴스 익스포트
    module.exports = new Logger('DEFAULT');
    
    
    //main.js
    const logger = require('./logger');
    logger.log('message');

    모듈이 캐시되기 떄문에 logger 모듈을 필요로 하는

    모든 모듈들은 실제로 항상 동일한 객체의 인스턴스를 검색하여 상태를 공유합니다.

    이 패턴은 싱글톤을 만드는 것과 매우 비슷합니다

    그러나 전통적인 싱글톤 패턴처럼 전체 어플리케이션에서 인스턴스의 고유성을 보장하진 않습니다

    모듈은 어플리케이션의 의존성 트리내에 여러 번 설치될 수 있다는것을 보았습니다.(npm2)

    결과적으로 동일한 논리적 모듈의 여러 인스턴스가 모두 동일한 Node.js 어플리케이션의 컨텍스트에서 실행될 수 있습니다(싱글톤 보장이 안된다)
    https://medium.com/@lazlojuly/are-node-js-modules-singletons-764ae97519af

    '@19.1 ~ > Nodejs' 카테고리의 다른 글

    프록시 패턴  (0) 2020.06.19
    노드 Promise 패턴  (0) 2020.06.11
    콜백 규칙 및 예외처리  (0) 2020.05.31
    Map, WeakMap  (0) 2020.05.31
Designed by Tistory.