말 그대로 계층이 있는 아키텍쳐.
각 계층은 수평적으로 구성이 되고, 각 계층마다 특정 역할을 한다.
보통은 아래의 4계층으로 구성된다.
하지만 Application의 규모에 따라서 3- 5 개 등의 구조를 가질 수 있음.
AOP처럼 횡단관심사로 분리해서 수평 계층으로 구성되어 각각의 layer는 하나의 관심사만 집중할 수 있도록 하는 것이다.
Layered Architecture에서는 각 계층마다 화살표를 통해 흐름을 이어간며 각 계층을 뛰어넘을 수 없다. ( Presentation → Persistence)
@RestController
@RequestMapping("/layered")
@RequiredArgsConstructor
public class TestController {
private final TestRepository testRepository;
private final TestService testService;
@Transactional
@GetMapping
public Test getUserInfo(TestReqDto reqDto) {
Optional<Test> byId = testRepository.findById(1L);
Test test = byId.orElse(new Test());
test.updateUserInfo(reqDto);
return testService.getUserinfo();
}
}
@Entity
@Table(name = "test")
public class Test {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 고유번호 PK
private String name; // 이름
private int age; // 나이
private String gender; // 성별
private String email; // 이메일
private String contact; // 연락처
public void updateUserInfo(TestReqDto updateDto) {
this.name = updateDto.getName();
this.gender = updateDto.getGender();
this.email = updateDto.getEmail();
this.contact = updateDto.getContact();
}
}
위의 코드와 같이 Controller에서 Domain 간의 관계가 밀접하게 연관이 되고, 변경사항이 Service와 Repository에 퍼지게 된다.
+추후 수정도 어려워진다.
때문에 각 계층은 서로에게 관심을 두지 않고 필요에 의해서 찾는 관계가 되어야한다.
사용자의 요청에 대해서 해석, 응답하는 계층
ex) Controller
@RestController
@RequestMapping("/layered")
@RequiredArgsConstructor
public class TestController {
private final TestService testService;
@GetMapping
public Test updateUser(TestReqDto reqDto) {
return testService.updateUserInfo(reqDto);
}
}
실질적인 비즈니스 로직을 처리하는 계층. (보통 Service를 뜻 함.)
도메인(Domain Layer)과 인프라스트럭쳐(InfraStructure Layer)를 연결
// 인터페이스
public interface TestService {
D_Test updateUserInfo(TestReqDto reqDto);
}
// 구현체
@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {
private final TestRepository repository;
@Override
public Test updateUserInfo(TestReqDto reqDto) {
if(reqDto.getId() == null || reqDto.getId() == 0) {
throw new CommonException("존재하지 않는 아이디 입니다.");
}
return repository.findById(reqDto.getId()).orElse(null);
}
}
DB에 접근하는 계층. Business에서 온 요청으로 조회 함.
DDD에서 쓸 때에는 도메인 레이어라고 부르는 것 같음
도메인 : 소프트웨어로 해결하고자 하는 문제 영역
예를 들어 쇼핑몰이 있다면 쇼핑몰 자체가 하나의 도메인이 되고,
그 아래
@Entity
@Table(name = "domain_test")
public class DomainTest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 고유번호 PK
private String name; // 이름
private int age; // 나이
private String gender; // 성별
private String email; // 이메일
private String contact; // 연락처
public void updateUserInfo(TestReqDto updateDto) {
this.name = updateDto.getName();
this.gender = updateDto.getGender();
this.email = updateDto.getEmail();
this.contact = updateDto.getContact();
}
}
Refference
https://velog.io/@jeb1225/DDD의-계층구조Layered-architecture
https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html