Clprolf를 사용한 클래스 책임 분리

발행: (2025년 12월 5일 오전 03:06 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

개요

깨끗하고 잘 구조화된 클래스를 설계하는 것은 객체‑지향 프로그래밍에서 핵심 과제입니다.
Clprolf는 declensions(활용형) 를 도입합니다 – 클래스의 성격과 속한 도메인을 간단히 표현하는 방법으로, 기존 아키텍처를 대체하지 않습니다. 레포지토리, 서비스, 컨트롤러, 엔티티, 추상화는 그대로 두고, 활용형을 추가하여 일관성을 보장합니다.

활용형(Declensions)

활용형은 클래스가 비즈니스/도메인 계층(agent)에 속하는지 기술 계층(worker_agent)에 속하는지를 나타냅니다. 이 용어는 자연어에서 단어가 사용에 따라 형태가 변하지만 핵심 정체성은 유지되는 개념을 차용한 것입니다.

주요 활용형

활용형전형적인 책임
agent비즈니스 로직, 도메인 개념, 추상화, 시뮬레이션 엔티티
worker_agent기술 구성 요소: 레포지토리, 화면 로직, 파일 작업, 시스템 상호작용, 실행기

동의어

같은 활용형 안에서 동의어는 도메인을 바꾸지 않으면서 의도를 더 명확히 합니다.

  • agent 동의어: abstraction (개념적 또는 구조적 요소, 예: List, Button, Color), simu_real_obj (시뮬레이션 내부 객체)
  • worker_agent 동의어: comp_as_worker (시뮬레이션 뉘앙스를 가진 동일 의미)

이 동의어들은 실제 도메인을 변경하지 않으며, 개발자에게 더 명확한 용어를 제공할 뿐입니다.

기존 구성 요소와의 통합

Clprolf는 Service, Repository, Controller 역할을 대체하지 않습니다. 이들 위에 활용형 주석을 추가하여 일관된 경계를 강제합니다.

전형적인 매핑

구성 요소 유형활용형
Repository / DAOworker_agent
Serviceagent
Controlleragent (또는 컨트롤러를 순수 기술 엔드포인트로 간주한다면 worker_agent)

상속 규칙

Clprolf는 구성 요소 간 상속을 간접적으로 감독합니다:

  • worker_agentagent를 상속할 수 없습니다 (예: 레포지토리가 서비스에서 상속되는 경우).
  • agent는 기술 클래스를 상속할 수 없습니다.
  • 같은 활용형을 가진 두 클래스는 상속이 가능하지만, 서로 다른 동의어를 사용할 경우 경고가 발생하여 관점 차이를 알립니다.

이 규칙은 우발적인 교차‑도메인 상속을 방지하고 시간이 지나도 책임을 명확히 유지하도록 돕습니다.

DDD 및 Clean Architecture와의 비교

  • DDD는 도메인을 모델링하고 유비쿼터스 언어를 유지하기 위해 관례와 팀 규율에 의존합니다.
  • Clean Architecture는 가이드라인, 패턴, 프로젝트 구조를 통해 도메인과 기술 계층을 분리합니다.
  • Clprolf는 언어 수준에서 도메인 ↔ 기술 역할을 강제하여, 아키텍처 경계를 컴파일러가 확인하도록 보장합니다.

따라서 Clprolf는 DDD와 Clean Architecture와 함께 작동하며, 이를 대체하지 않고 추가적인 안전성을 제공합니다.

접근 방식 비교

접근 방식초점강제 방식
DDD도메인 모델링, 유비쿼터스 언어관례 및 팀 규율
Clean Architecture도메인 ↔ 기술 계층 분리가이드라인, 패턴, 프로젝트 구조
Clprolf활용형: 도메인 ↔ 기술 역할컴파일러가 확인하고 언어 차원에서 강제

사용 예시 (Java)

// Business logic (agent)
@Agent
public class OrderService {

    private final OrderRepository repository = new OrderRepository();

    public void validateAndStore(String orderId) {
        // Business logic
        System.out.println("Validating order " + orderId);

        // Technical operation delegated to a worker_agent
        repository.save(orderId);
    }
}
// Technical work (worker_agent)
@Worker_agent
public class OrderRepository {

    public void save(String orderId) {
        System.out.println("Saving order " + orderId);
    }
}
// Illegal inheritance – compilation error
@Worker_agent
public class WrongRepo extends OrderService {
    // ❌ A worker_agent cannot inherit from an agent.
}
// Domain object (agent)
@Agent
public class Animal {

    public void eat(String food) {
        System.out.println("The animal eats " + food);
    }
}
// Service using technical workers
@Agent
public class CheckoutService {

    private final OrderRepository orders = new OrderRepository();
    private final PaymentRepository payments = new PaymentRepository();

    public void checkout(String orderId) {
        orders.save(orderId);
        payments.process(orderId); // Technical operation
    }
}

위 예시들은 다음을 보여줍니다:

  • 기존 구성 요소(Service, Repository, Controller)는 그대로 유지됩니다.
  • @Agent 혹은 @Worker_agent를 추가함으로써 각 클래스의 도메인이 명확해집니다.
  • 상속은 비즈니스 ↔ 기술 구분을 존중하여 우발적인 혼합을 방지합니다.

장점

  • 비즈니스와 기술 로직의 명확한 분리
  • 컴파일러가 확인하는 경계로 우발적인 교차‑도메인 상속 방지
  • 활용형 동의어를 통한 일관된 용어
  • SOLID 원칙, DDD, Clean Architecture와 호환
  • 신규 개발자를 위한 예측 가능하고 가독성 높으며 유지보수 쉬운 코드베이스

추가 자료

전체 Clprolf 매뉴얼, 사양, 프레임워크 소스 코드는 다음에서 확인할 수 있습니다:

https://github.com/charleskoffler/clprolf

Back to Blog

관련 글

더 보기 »

2026년 시스템 디자인 완전 가이드

소개 나는 지난 10년 가까이 엔지니어가 새로운 스킬을 배우고 커리어를 레벨업할 수 있도록 돕는 다양한 방법에 대해 글을 써 왔다. 나는 두 가지 훌륭한…

Java OOPS 개념

Forem 로고https://media2.dev.to/dynamic/image/width=65,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%...