말 그대로 계층이 있는 아키텍쳐.
각 계층은 수평적으로 구성이 되고, 각 계층마다 특정 역할을 한다.
보통은 아래의 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