개요

데이터 구조를 값으로 다루면, 복사된 값을 사용하게 된다. 일반적으로 권장되는 사용 방식이다.

데이터 구조를 참조로 다루면, 같은 데이터를 여러 곳에서 공유하게 된다.

 

보통은 데이터 구조를 값으로 다루는 것을 권장하나, 값을 갱신해야하는 경우는 예외다. 값으로 다룬다면, 복사본을 모두 찾아 수정해줘야한다.

보통 이런 경우 하나의 객체만 존재하게 된다. 이를 관리하는 저장소를 만들어 관리하는 좋다.

이렇게 되면 저장소를 통해서만 객체에 접근이 가능하다.

예시

class Order {
    constructor(data){
        this._number = data.number;
        this._customer = new Customer(data.customer);
        //여러 데이터 data.customer == id
    }
    get customer(){return this._customer;}
}
//불변 객체다.
class Customer{
    constructor(id){
        this._id = id;
    }
    get id(){return this._id;}
}
불변 객체라 같은 고객의 주문이 들어올때 마다 고객 객체가 늘어난다.
만약 고객 데이터가 변경된다면 복사본 모두를 변경해야 한다.


//물리적으로 똑같은 객체를 저장할 곳
let _repositoryData;//저장소 객체
export function initialize(){
    _repositoryData = {};
    _repositoryData.customers = new Map();
}
export function registerCustomer(id){
    if(!_repositoryData.customers.has(id)){
        _repositoryData.customers.set(id, new Customer(id));
    }
    return findCustomer(id);
}
export function findCustomer(id){
    return _repositoryData.customers.get(id);
}
프로젝트에 쓸만한 저장소가 존재한다면 그것을 사용해도 무방하다.
아래는 노드 모듈로 변환


import {findCustomer, initialize,registerCustomer,_repositoryData} from './repository.mjs';
export class Order {
    constructor(data){
        this._number = data.number;
        this._customer = new Customer(data.customer);
        //여러 데이터...
    }
    get customer(){return this._customer;}
}
//불변 객체다.
export class Customer{
    constructor(id){
        this._id = id;
    }
    get id(){return this._id;}
}
initialize();
registerCustomer("100");
registerCustomer("200");
registerCustomer("100");
console.log(findCustomer("100"));
console.log(_repositoryData);
////////////////////////////////////////////////////
import {Order, Customer} from './ex1.mjs'
//물리적으로 똑같은 객체를 저장할 곳
export let _repositoryData;//저장소 객체
export function initialize(){
    _repositoryData = {};
    _repositoryData.customers = new Map();
}
export function registerCustomer(id){
    if(!_repositoryData.customers.has(id)){
        _repositoryData.customers.set(id, new Customer(id));
    }
    return findCustomer(id);
}
export function findCustomer(id){
    return _repositoryData.customers.get(id);
}



완료


/* ex1.mjs */
import {findCustomer, initialize,registerCustomer,_repositoryData} from './repository.mjs';
export class Order {
    constructor(data){
        this._number = data.number;
        this._customer = registerCustomer(data.customer);
        //여러 데이터...
    }
    get customer(){return this._customer;}
}
//불변 객체다.
export class Customer{
    constructor(id){
        this._id = id;
    }
    get id(){return this._id;}
    set id(arg){this._id = arg;}
}
initialize();


const customer1 = new Customer("10");
const orders = [];
orders.push(new Order({number:1 , customer:"10"}));
orders.push(new Order({number:2 , customer:"10"}));
orders.push(new Order({number:3 , customer:"10"}));
orders.push(new Order({number:4 , customer:"10"}));
console.log(_repositoryData);
orders.forEach(o=>console.log(o));
findCustomer("10").id = "20";
orders.forEach(o=>console.log(o));


/*repository.mjs */
import {Order, Customer} from './ex1.mjs'
//물리적으로 똑같은 객체를 저장할 곳
export let _repositoryData;//저장소 객체
export function initialize(){
    _repositoryData = {};
    _repositoryData.customers = new Map();
}
export function registerCustomer(id){
    if(!_repositoryData.customers.has(id)){
        _repositoryData.customers.set(id, new Customer(id));
    }
    return findCustomer(id);
}
export function findCustomer(id){
    return _repositoryData.customers.get(id);
}



 

고객 정보를 갱신하면 같은 고객을 공유하는 모든 주문에서 갱신된다.

다만, 방법에서 저장소가 전역 객체다. 전역 객체가 꺼림직 하다면 생성자 주입으로 저장소 객체를 주입하는 것도 방법이다.

 

 

+ Recent posts