본문 바로가기
Spring Study

Separation of Concerns(관심사 분리)

by xogns93 2024. 8. 5.

관심사의 분리(Separation of Concerns) 원칙 설명

"관심사의 분리(Separation of Concerns, SoC)"는 소프트웨어 설계에서 중요한 원칙 중 하나입니다. 이 원칙은 프로그램의 각 부분이 서로 다른 기능이나 관심사에만 집중하도록 설계되어야 한다는 것을 의미합니다. 이를 통해 코드의 가독성, 유지보수성, 재사용성이 크게 향상됩니다. 자바에서는 클래스를 통해 관심사를 분리할 수 있으며, 다양한 방법으로 구현될 수 있습니다. 대표적인 예로는 모듈화, 계층화, 컴포넌트 기반 개발 등이 있습니다.

 

주요 개념

  1. 모듈화: 프로그램을 기능별로 분리된 모듈로 나누어, 각 모듈이 특정 역할만 수행하도록 합니다.
  2. 응집도: 각 모듈 내의 요소들이 얼마나 밀접하게 관련되어 있는지를 나타내며, 높은 응집도를 유지해야 합니다.
  3. 결합도: 모듈 간의 상호 의존성을 나타내며, 낮은 결합도를 유지해야 합니다.

 

자바 예제: 쇼핑 애플리케이션

이 예제에서는 간단한 쇼핑 애플리케이션을 만들어 보겠습니다. 주요 구성 요소는 상품 정보를 관리하는 Product, 데이터베이스 접근을 담당하는 ProductDao, 비즈니스 로직을 처리하는 ProductService, 그리고 사용자 인터페이스를 관리하는 ProductController로 구성됩니다.

1. 도메인 모델 (Domain Model) - Product.java

도메인 객체는 비즈니스 개념을 표현하며, 사용자 정보를 나타내는 Product 클래스입니다.

public class Product {
    private int id;
    private String name;
    private double price;

    public Product(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    // Getter와 Setter 메소드
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

2. 데이터 액세스 오브젝트 (DAO) - ProductDao.java

DAO 클래스는 데이터베이스와의 상호작용을 담당합니다. 

import java.util.ArrayList;
import java.util.List;

public class ProductDao {
    private List<Product> products = new ArrayList<>();

    public ProductDao() {
        products.add(new Product(1, "Coffee Maker", 99.99));
        products.add(new Product(2, "Toaster", 49.95));
    }

    public List<Product> getAllProducts() {
        return products;
    }

    public Product getProductById(int id) {
        return products.stream()
            .filter(product -> product.getId() == id)
            .findFirst()
            .orElse(null);
    }
}

3. 비즈니스 로직 (Service) - ProductService.java

비즈니스 로직 클래스는 도메인 객체와 DAO 객체를 사용하여 비즈니스 규칙을 처리합니다.

public class ProductService {
    private ProductDao productDao;

    public ProductService(ProductDao productDao) {
        this.productDao = productDao;
    }

    public Product getProduct(int id) {
        return productDao.getProductById(id);
    }

    public List<Product> listProducts() {
        return productDao.getAllProducts();
    }
}

4. 컨트롤러 (Controller) - ProductController.java

컨트롤러 클래스는 사용자 요청을 처리하고, 비즈니스 로직을 호출하며, 결과를 뷰에 전달합니다.

public class ProductController {
    private ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    public void displayProduct(int productId) {
        Product product = productService.getProduct(productId);
        if (product != null) {
            System.out.println("Product Details: ID=" + product.getId() + ", Name=" + product.getName() + ", Price=$" + product.getPrice());
        } else {
            System.out.println("Product not found.");
        }
    }

    public void displayAllProducts() {
        productService.listProducts().forEach(product ->
            System.out.println("Product: ID=" + product.getId() + ", Name=" + product.getName() + ", Price=$" + product.getPrice())
        );
    }
}

이 예제에서 각 클래스는 자신의 관심사에 집중하며, 서로의 코드를 직접적으로 알지 못해도 동작합니다. 이를 통해 유지보수가 용이하고, 각 컴포넌트의 재사용성이 향상됩니다. 이런 방식으로 설계하는 것이 관심사의 분리의 핵심입니다.