도서/기술

[책] 데이터 지향 프로그래밍 - 2장 코드와 데이터 분리

egg528 2024. 11. 24. 15:14

 

DOP 원리 1
코드를 함수 안에 두는 방식으로 데이터에서 코드를 분리한다. 함수의 동작은 어떤 식으로든 함수 컨텍스트에 캡슐화된 데이터에 따라 달라져서는 안 된다.

 

 

시스템을 바라보는 방식 - 코드, 데이터


 

 데이터 지향 프로그래밍(DOP)에서 시스템은 코드와 데이터 2가지로 나뉜다. OOP에서는 캡슐화를 통해 클래스 내부에 데이터는 필드로, 코드는 함수로 함께 존재하지만 DOP에서는 캡슐화에 반대한다. 그 이유는 데이터와 코드가 혼합되어 있다는 점이 시스템의 복잡성과 경직성을 유발하기 때문이라 말한다.

 

 

1. 데이터 개체

 데이터 개체는 시스템의 정보를 보관하는 부분이다. 도서관 시스템에서 필요한 데이터를 마인드맵으로 정리하면 이 정도로 나타낼 수 있다.

 

 

2. 코드 모듈

  코드 모듈은 시스템의 기능이다. 책에서는 외부에 공개되어야 할 API들로 Library라는 상위 모듈을 구성하고 이전에 정의한 2가지 데이터 개체를 다룰 2가지 모듈을 추가했다. 코드 모듈에는 2가지 특징이 있는데 하나는 무상태 함수라는 점이고 또 하나는 사용 관계만 존재할 수 있다는 점이다. 명세에서도 볼 수 있겠지만 각 메서드에서 다룰 데이터는 인자로 받아서 사용하고 Library는 UserManagement와 Catalog를 사용하고 있다.

 

 

시스템의 부분 구성 요소에 대한 제약 관계의 제약
데이터 개체 순수 데이터 연관과 포함
코드 모듈 무상태 함수 사용

 

 

코드와 데이터를 분리해 얻은 유연성


 코드와 데이터를 분리하여 시스템을 구성하면 확장과 변경을 수용하기 쉽다고 한다. OOP에서 아래 2가지 추가 기능을 구현하기 위해 상속을 활용하는 기능을 살펴봤다. 그 결과 점차 상속 관계가 복잡해지는 결과를 가져왔다.

  1. 슈퍼 회원은 다른 회원에게 대출된 도서의 목록을 조회할 수 있는 회원이다.
  2. VIP 회원은 도서관에 책을 추가할 수 있는 회원이다.

 

// AS-IS
class Library {
    static getBookLendings(libraryData, userId, memberId) {
        if (UserManagement.isLibrarian(libraryData.userManagement, userId)) {
            return Catalog-getBookLendings(libraryData.catalog, memberId);
        } else {
            throw "대출된 도서를 조회할 권한이 없음" ;
        }
    }
}

// TO-BE
class Library {
    static getBookLendings(libraryData, userId, memberId) {
        if (UserManagement.isLibrarian(libraryData.userManagement, userId) ||
           UserManagement.isSuperMember(libraryData.userManagement, userId)
        ) {
            return Catalog-getBookLendings(libraryData.catalog, memberId);
        } else {
            throw "대출된 도서를 조회할 권한이 없음" ;
        }
    }
}

 예를 들어 1번 기능을 추가하려면 isSuperMember 메서드를 구현하고 getBookLendings 메서드에서 구현된 메서드를 사용해 조건문을 조금만 수정해주면 된다. 2번 기능 또한 동일한 작업으로 완료할 수 있다. 이전 OOP의 상속에서 기능 추가를 위해 시스템 설계를 수정했던 것에 비해 간단한 작업으로 추가 기능을 반영한 걸 확인할 수 있다.