요즘은 소스 라이브러리에서 웹서버를 들고있다
tomcat 등을 따로 깔 필요가 없음
controller package 만들고
HelloController java class 를 만들어서
GetMapping -> get method 이다
Model 안에서
"data" 라는 키 값의 "이 값을 가져가서" 라는 value 를 가지고
넘어가
(viewResolver 가 이렇게 처리해준다)
viewName.html 파일을 찾아간다
resources 의 template 밑에 있는 hello 를 찾아서 간다
spring-boot-devtools 라이브러리를 추가하면 서버를 재시작할 필요 없이 view 파일 변경이 가능하다
역할과 구현을 분리
역할 - 인터페이스
구현 - 클래스, 객체
클라이언트 - 요청 // 서버 - 응답
-> 클라이언트를 변경하지 않고 객체의 서버의 구현 기능을 유현하게 변경할 수 있다!!
인터페이스가 변경되면 클라이언트, 서버 모두에 큰 변경이 발생한다!!
-> 인터페이스를 안정적으로 세팅하는 것이 중요
하나의 클래스는 하나의 책임을 가져야 한다
여기서의 책임이란 변경.. 변경이 있을 때 파급 효과가 적어야 한다
확장에는 열려있으나 변경에는 닫혀 있어야 한다
ex) 어떤 자동차로 바꿔도 클라이언트는 운전이 가능
-> java 에서는 인터페이스를 구현한 새로운 클래스 하나를 만들어 새로운 기능을 구현
-> 문제점
MemberRepository m = new MemoryMemberRepository(); // 기존 코드
MemberRpository m = new JdbcMemberRepository(); // 변경된 코드
DI 를 하기 위해서 MemberService( 즉 클라이언트 ) 가 변경되어야 한다
=> 해결방안
객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요!!
이 역할을 spring 에서 해준다
객체는 프로그램의 정화성을 꺠뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다
특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다
=> 인터페이스가 명확해지고 대체 가능성이 높아진다
"추상화에 의존해야 하고 구체화에 의존하면 안된다"
ex) MemberService => MemberRepositoryInterface 만 바라봐야 하고
MemoryMemberRepository , JdbcMemberRepository 는 몰라야 한다
역할에 의존하게 구조를 구성하는 것!
public class MemberService {
private MemberRepository memberRepository = new MemoryMemberRepository();
}
이 코드는 Service (인터페이스) 는 MemberRepository (구현 클래스) 를 직접 선택했다 => DIP 위반
다양한 부품을 조합해 하나의 완성된 프로그램을 조립한다
재사용성이 높지만 오래걸린다
다형성, OCP, DIP 원칙을 지키며 개발하기 쉽게 만들어둔 환경!!