고민. 비즈니스 로직과 View의 의존성 배제하기
비즈니스 로직을 담당하는 Domain
과
입출력을 담당하는 View
의 의존관계을 완전히 배제하고 싶었다.
분리를 위해 Domain
과 View
의 의존관계를 동시에 가지는 Controller
를 생성했다.
이렇게 객체를 분리함으로써 로직상의 물리적인 의존관계는 완벽하게 사라졌다.
만약에 화면단에서 표현되는 Car
의 진행도를 bar(’-
’)가 아닌 다른 문자열로 변경하고 싶다면?
흐름상 코드의 변경은 View
에서 이루어지는 게 자연스럽다고 생각되지만,
아래 처럼 현재 로직에서는 Car
에서 코드를 변경해야 한다.
변경 전
public class Car implements Comparable<Car> {
// TODO: View와 명시적으로 남아있는 의존성을 분리하기
private static final String CAR_INFO_FORMAT = "%s : %s\n";
private static final String POSITION_EXPRESS_CHARACTER = "-";
@Override
public String toString() {
String position = this.expressPosition();
return String.format(CAR_INFO_FORMAT, this.name, this.position);
}
}
이렇게 메모리상 의존관계를 배제했음에도
여전히 Car
객체가 자신의 상태를 표현하는 부분은 View
와 깊게 의존하고 있다.
이를 구분지을 순 없을까?
변경 후
여러 방법을 모색해본 결과 DTO
를 활용하는 게 가장 깔끔해 보였다.
View
레이어에 데이터를 전달하기 위해 CarDto
를 Car
내부에서 반환하도록 했다.
이번 미션은 Java17
을 사용하기때문에 record
도 사용해보았다.
public class Car implements Comparable<Car> {
public CarDto getStatus() {
return new CarDto(this.name, this.position);
}
}
public record CarDto(String name, int position) {
}
위의 Dto를 Controller에서 View로 전달하기 때문에
Domain과 View의 의존관계를 완벽하게 끊어낼 수 있었다.
결론 및 느낀점
처음에는 비즈니스 로직과 View의 물리적 의존성을 끊기 위해
중간 레이어인 Controller를 생성했고, Car 객체에서 출력을 위한 문자열을 저장했었습니다.
이로써 물리적인 의존성은 배제되었지만 아직 논리적인 의존성은 남아있었습니다.
만약에 화면단에서 표현되는 Car의 진행도를 bar(-)가 아닌 다른 문자열로 변경하고 싶다면?
흐름상 코드의 변경은 View에서 이루어지는 게 자연스럽다고 생각되지만, Car에서 코드를 변경해야 했습니다.
이를 위해 DTO를 도입하였습니다.
각 객체 캡슐화를 최대한 깨뜨리지 않기 위해 본인의 데이터를 가지는 DTO는 각 객체 내에서 생성하도록 했고 Controller 레이어에서 출력을 위한 DTO를 반환받아 View로 전달했습니다.
이로써 물리적, 논리적인 의존관계가 사라졌습니다.
항상 MVC에 대해 의문이 있었습니다. 왜 굳이 레이어를 나눈것일까?
이번 과제에서 의존성을 배제하며 느낀 결과 레이어를 분리했을 때, 각 레이어는 담당하는 역할만 수행하면 된다는 장점, 이는 곧 변경에 유연해진다는 결론에 도달할 수 있었습니다.
'JAVA' 카테고리의 다른 글
데몬 스레드 (Daemon Thread) (2) | 2024.01.01 |
---|---|
GC 짚고 넘어가기 (1) | 2023.12.29 |
[JAVA 객체지향] getter의 사용을 지양하고 객체간 대화로 해결하자 (0) | 2023.10.30 |
[JAVA] 접근자 메서드(getter/setter)를 왜 써야할까? (0) | 2023.05.25 |
[Java] DIP - 의존성? 의존성 역전? (0) | 2023.04.26 |