SW 개발 일반/클린 코드

클린 코드: MAPPER 원칙

growdai1y 2025. 2. 5. 17:21

클린 코드(clean code)는 로버트 C. 마틴(Robert C. Martin)의 저서에서 제안된 개념으로, 이해하기 쉽고, 변경하기 용이하며, 예측 가능해야 한다는 특징을 갖습니다. 클린 코드를 달성하는 방법 중 하나는 OOP 원칙을 따르는 것입니다. OOP는 현실 세계의 개념을 모델링하는 방식으로, 객체와 클래스를 활용해 소프트웨어 시스템을 구성합니다.

 

하지만 단순히 객체를 사용하는 것만으로는 클린 코드가 보장되지 않습니다. 잘못된 객체 모델링은 오히려 복잡성을 증가시키고, 유지보수를 어렵게 만들 수 있습니다. 이러한 문제를 해결하기 위해 등장한 것이 바로 MAPPER 원칙입니다.


MAPPER 원칙이란?

현실 세계를 반영하는 소프트웨어 설계 원칙에서 설명한 내용을 MAPPER라는 원칙으로 설명하는 책이 있어 관련 내용을 아주 간단하게 정리하려고 합니다.

실무로 통하는 클린 코드
https://www.yes24.com/Product/Goods/130025081

 

MAPPER 원칙은 객체가 현실 세계를 정확히 반영해야 한다는 개념을 기반으로 한 설계 원칙입니다. 이는 현실의 개체(entity)와 소프트웨어의 객체(object) 사이의 1:1 대응 관계를 유지하도록 유도합니다.

MAPPER 원칙의 구성 요소

MAPPER = Model: Abstract Partial and Programmable Explaining Reality

  • Model (모델화): 소프트웨어는 현실 세계의 개념을 반영해야 합니다. 객체는 단순한 데이터 저장소가 아니라, 행동을 포함하는 개체여야 합니다.
  • Abstract (추상화): 객체의 행동이 무엇인지 명확하게 표현해야 하며, 구현 세부사항이 아니라 동작에 집중해야 합니다.
  • Partial (부분적 표현): 현실의 모든 요소를 소프트웨어에 반영할 필요는 없으며, 필요한 부분만을 추출해야 합니다.
  • Programmable (실행 가능성): 모델은 실행 가능한 형태로 존재해야 하며, 단순한 문서가 아니라 동작하는 코드여야 합니다.
  • Explaining (설명 가능성): 코드의 동작이 논리적으로 설명 가능해야 합니다. 단순히 실행만 되는 것이 아니라, 왜 그렇게 동작하는지 이해할 수 있어야 합니다.
  • Reality (현실과의 연결): 객체는 현실 세계의 개체와 일관성을 유지해야 합니다. 비즈니스 로직과 도메인 개념을 그대로 반영하는 것이 중요합니다.

MAPPER 원칙을 적용한 OOP 예제

MAPPER 원칙을 적용하기 위해서는 객체를 단순한 데이터 컨테이너로 다루지 않고, 현실의 역할과 행동을 반영하는 개체로 설계해야 합니다. 예를 들어, 전통적인 Employee 클래스를 개선하는 방법을 살펴보겠습니다.

잘못된 설계 (데이터 중심, Anemic Model)

public class Employee {
    public String name;
    public int id;
}

단순한 데이터 저장 객체로서, 현실에서 직원이 수행하는 행동이 포함되지 않습니다.

올바른 설계 (MAPPER 원칙 적용)

public class Employee {
    private String name;
    private int id;
    private Salary salary;
    private Position position;
    private AttendanceRecord attendance;

    public Employee(String name, int id, double baseSalary, String title, String department) {
        this.name = name;
        this.id = id;
        this.salary = new Salary(baseSalary);
        this.position = new Position(title, department);
        this.attendance = new AttendanceRecord();
    }

    public void giveRaise(double amount) { salary.increaseBaseSalary(amount); }
    public void promote(String newTitle) { position.changeTitle(newTitle); }
    public void clockIn() { attendance.clockIn(); }
    public List<String> getAttendanceLogs() { return attendance.getLogs(); }
}

급여 관리, 승진, 근태 기록 등 직원의 실제 행동을 반영하여 MAPPER 원칙을 준수합니다.


Employee 모델을 활용한 급여 관리 시나리오

MAPPER 원칙에서 중요한 점은 모델이 현실과 긴밀히 연결되며, 실제 유스케이스를 이야기할 수 있어야 한다는 것입니다. 다음은 Employee 모델을 활용한 급여 관리 시나리오입니다.

 

시나리오:

  1. 직원 김철수는 입사 시 연봉 50,000달러를 받습니다.
  2. 1년 후 성과를 인정받아 연봉이 5,000달러 인상됩니다.
  3. 6개월 후 특별 성과 보너스 2,000달러가 지급됩니다.
Employee kim = new Employee("김철수", 1001, 50000, "Software Engineer", "IT");
System.out.println("초기 연봉: " + kim.getTotalSalary());

// 연봉 인상
kim.giveRaise(5000);
System.out.println("연봉 인상 후: " + kim.getTotalSalary());

// 보너스 지급
kim.giveBonus(2000);
System.out.println("보너스 지급 후: " + kim.getTotalSalary());

 

예이기 때문에 완전할 수는 없지만 현실과 흡사한 시나리오를 코드로 표현할 수 있으며, 이를 통해 소프트웨어 모델이 실제 업무를 반영하는 방식이 명확해집니다.

 

앞선 예제에서는 코드를 활용했지만, 모델이 완전하지 않더라도 동료들과 함께 특정 유스케이스에 대해 역할극(Role-play)을 진행할 수 있습니다. 즉, 코드 없이 정리된 모델의 객체를 기반으로 시뮬레이션을 수행하는 것입니다. 처음에는 다소 어색할 수 있지만, 역할극을 거듭할수록 추상적인 개념이 더욱 명확해지고, 문제에 대한 이해도가 동료들 간에 동기화됩니다. 이는 동료들과 문제에 대한 멘탈 모델을 동기화하여, 보다 좋은 코드로 이어질 수 있는 토대를 마련하는 데 기여합니다.


결론

MAPPER 원칙을 적용하면 데이터 중심 설계에서 행동 중심 설계로 전환할 수 있으며, 객체의 역할과 책임을 명확히 정의할 수 있습니다. 이를 통해 보다 명확하고 직관적인 소프트웨어 아키텍처를 구축할 수 있습니다.

 

 

반응형

'SW 개발 일반 > 클린 코드' 카테고리의 다른 글

디미터 법칙 (Law of Demeter)  (0) 2025.03.21
빈약한 객체 (Anemic Object)  (0) 2025.03.07