GitHub

https://github.com/Choidongjun0830

Spring

[원티드 백엔드 챌린지 11월] 객체지향스러운 아키텍쳐 설계

gogi masidda 2024. 11. 22. 15:36

Encapsulation

  • 객체의 변수와 메서드를 하나로 묶고, 실제 구현 내용 일부를 외부에 감추는 기술 
  • public API를 구현하는데 사용되는 내부 상태와 행동을 내부로 숨기는 것
  • 접근 제한자를 이용해서 캡슐화를 설계 및 적용

 

  • 캡슐화를 지키지 않으면 생기는 문제들
    • 캡슐화를 지켰을 때 얻을 수 있는 변경의 유연함을 잃어버림
      • 예를 들어, 변수가 public이라 client가 변수의 값을 직접 수정했는데, 만약 변수명이 바뀌어버린다면, client가 직접 쓴 변수명도 같이 수정해주어야 한다. 
    • 불변식이 깨져서 설계자의 의도대로 동작을 하지 않아 예외가 발생할 수도 있다. 
  • => 최대한 모든 요소를 private으로 선언해놓고, 접근 가능 범위를 한단계 (default > protected > public)씩 넓혀가는 방식으로 개발하는 것이 좋다. 

추상화 vs 인터페이스

  • 추상화; 상속; is-a
    • Car class
      • Electronic Car, Gasoline Car, Dissel Car
  • 인터페이스; 합성; has-a
    • 보통은 추상화보다는 인터페이스
      • 상속으로 인한 결합도가 높아져서 변경의 전염성이 자식까지 전파되는 문제를 일으킴
      • 불필요한 인터페이스까지 상속해서 자식 클래스 내부 규칙을 무너뜨리는 문제를 일으킴
        • Stack은 선입후출을 따라야 하는데, Java의 Stack 클래스는 중간에 요소를 넣을 수 있게 되는 것처럼.  
      • 클래스 조합 폭발 문제 발생
      • 메서드 오버라이딩의 오작용으로 의도와 다르게 동작하여 오류를 일으킨다. 
    • 자바 7까지는 인터페이스에 새로운 메서드가 추가될 일은 영원히 없다라는 가정 아래에 설계가 되었다. 하지만, 이제 인터페이스도 변화한다. 
      • -> default 메서드: 인터페이스에 새롭게 추가되는 메서드를 구현해서 모든 구현체에게 기본적으로 제공하는 방식. 만약 기본적으로 제공되는 기능을 변경해야 하면, @Override 사용 
        • 하지만 default 메서드가 모든 구현체와 조화를 이뤄서 동작하지는 않을 것이다. 

※ Optional의 null 검증 메서드는 객체의 메서드 실행 결과가 null인지 확인하기 위한 용도로 사용
    Objects.requireNonNull()은 메서드와 생성자에서 파라미터를 검증하기 위해 구현됨. 


DDD = OOP + SOLID

  • Domain Driven Development 
  • 패턴과 설계 그리고 아키텍처까지 합쳐놓은 새로운 개발 패러다임
  • 가장 많이 사용하는 프로젝트 구조(계층형: Controller - Service - Repository)가 데이터 중심의 설계 방식이였다면, DDD는 도메인 중심으로 설계 및 구현하는 방식 

Domain

  • SW로 문제를 해결하고자 하는 비즈니스 영역
    • ex. 이커머스, 핀테크, 성형 플랫폼, 금융 플랫폼 
  • 작은 의미로는 비즈니스를 구성하는 하나의 요소(업무 or 모듈)로써, 유사한 업무의 집합체
    • 결제 파트, 주문 파트, 고객 파트, 배송 파트 

 

  • DDD에서 하나의 Aggregate(Entites + Value Objects)는 설계상 완전한 한 개의 도메인 영역(모델)을 표현
    • 도메인 모델은 영속성을 가져야 한다.
      • 주문 정보, 결제 정보, 고객 정보 등 업무에 사용되는 데이터 
    • Entity는 ID를 갖고 있는 것, Value는 값 (money 같은거) 
  • 그렇기 때문에 우리가 정의한 Aggregate에 JPA와 관련된 어노테이션을 선언하고 ORM의 주체가 되어야 한다.
  • 영속성을 관리하는 Repository는 Aggregate 단위 별로 생성된다.
    • 데이터의 일관성을 유지하기 위해

 

고수준 모듈과 저수준 모듈

  • 고수준 모듈
    • 도메인(비즈니스)에서 제공해야 하는 기능을 온전하게 제공하는 단일 기능(or 메서드)를 말한다. 
    • Application Layer(Service Layer)의 Methods를 고수준 모듈이라고 말할 수 있다.
  • 저수준 모듈
    • 고수준 모듈은 작은 메서드들로 구성. 이 메서드를 저수준 모듈이라고 한다. 
    • 독립적으로 온전한 기능을 제공할 수는 없는 메서드를 말한다. 

 

SOLID의 DIP

  • 의존 관계를 맺을 때 변하기 쉬운 것에 의존하기 보다는 쉽게 변하지 않는 것이 의존하라는 원칙 
    • 쉽게 변하지 않는 것?
      • 아이가 가지고 노는 장난감의 종류는 항상 변하니까 구체적인 객체(모형 자동차, 인형, 레고 등)을 직접 의존하지 않고 Toy라는 클래스로 상위 개념을 만들어 의존하도록.
      • => 아이가 장난감을 가지고 논다라는 개념은 안변하게 

 

헥사고날 아키텍처

  • 전통적인 계층형 아키텍처의 단점을 보완하여 도메인 중심의 구조로 클린 아키텍처를 일반화한 아키텍처를 말한다.
  • 비즈니스 로직은 도메인(엔티티) 안에 있음 -> 변경해야 하는 지점이 도메인으로 한정됨. 
  • 패키지 구조에서 Representation과 Application 계층은 구현체가 들어가면 안된다. 
  • 패키지 구조 - Application; 응용 영역
    • 사용자가 요청한 기능을 실행. 업무 로직을 직접 구현하지 않으며 도메인 계층을 조합해서 기능을 실행
    • 도메인 계층에 구현된 비즈니스의 핵심 규칙들을 조합해서 온전한 기능 제공 
728x90