스프링은 자바를 기반으로 한 기술!
자바에서 가장 중요하게 가치를 두는 것은 객체지향
So, 스프링이 가장 관심을 많이 두는 대상은 오브젝트 입니다.
스프링을 이해하려면 먼저 오브젝트에 깊은 관심을 가져야 하며, 애플리케이션에서 오브젝트가 생성되고
다른 오브젝트와 관계를 맺고, 사용되고, 소멸하기까지의 전 과정을 이해하고 있어야합니다.
오브젝트에 대한 관심은 오브젝트의 설계에 대한 관심으로 발전
객체지향 기술과 설계, 구현에 관한 실용적인 전략을 개발자들이 자연스럽고 손쉽게 적용할 수 있도록 프레임워크 형태로 제공
아래의 3가지 repository
, service
, domain
을 활용하여 아무 설정도 안되어 있는 난감한
상태에서 제가 학습한 나름대로 Ver 1. 부터 Ver 5. 까지의 스프링이 지향하는 상태로의 발전을 보여드리겠습니다.
repository
JPA
를 사용하겠습니다.service
domain
User.java (모든 Version 에서 사용할 도메인)
@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id @GeneratedValue
@Column(name="user_id")
private Long id;
private String name;
private String password;
@Builder(builderMethodName = "createUser")
public User(String name,String password){
this.name=name;
this.password=password;
}
}
repository
클래스만 존재UserRepositoryV1.java
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Transactional
public class UserRepositoryV1 {
private final EntityManager em;
public Long join(User user) {
return save(user);
}
public User findOne(Long userId) {
Optional<User> findUser = findById(userId);
return findUser.orElseThrow(() -> {
throw new RuntimeException();
}
);
}
public Long save(User user) {
em.persist(user);
return user.getId();
}
public Optional<User> findById(Long id) {
return Optional.ofNullable(em.find(User.class, id));
}
public void remove(Long id) {
User user = findOne(id);
em.remove(user);
}
}
UserRepositoryV1Test.java(동작 확인)
@Transactional
@SpringBootTest
public class UserRepositoryV1Test {
@Autowired
EntityManager em;
@Test
@DisplayName("데이터 저장 테스트")
void 회원저장_Test(){
User user=User.createUser()
.name("홍성진")
.password("1234")
.build();
UserRepositoryV1 userRepository=new UserRepositoryV1(em);
Long saveId = userRepository.save(user);
User findUser = userRepository.findOne(saveId);
Assertions.assertThat(findUser.getName()).isEqualTo(user.getName());
Assertions.assertThat(findUser.getPassword()).isEqualTo(user.getPassword());
}
}
테스트 결과
이런 식으로 repository
클래스만 딱 쓰는 것은 객체지향관점에서 굉장한 문제를 초래한다고 합니다.
이러한 고찰(좋은 객체지향 설계)이 스프링을 활용한 개발의 첫 걸음이 되었다고 합니다.
관심사의 분리
분리
모든 변경과 발전은 한 번에 한 가지 관심사항에 집중해서 일어납니다.
So, 문제를 해결하기 위해? 공통 관심사항을 가진 것들을 한 곳에 집중시키면 됩니다.
관심이 같은 것끼리는 하나의 객체 안으로 , 다른 것은 따로 떨어져 서로 영향을 끼치지 않도록 하는 것입니다.
분리의 예
만약, repository
의 로직을 상황에 따라 바꾸고 싶다고 가정해 봅시다.
하지만, 현재, Ver 1. 에서는 repository
클래스 하나로만 구성되어 있습니다. 즉, 사용 시점마다 원하는 로직에 대한 코드로의 번거로운 수정이
필요하게 됩니다. 또한, 이 클래스를 개발한 개발자가 그만두고 다른 개발자가 이어서 작업을 한다고 생각한다면, 어느 부분을 수정해야 할 지도
모를 수 있으며 관심사가 다른 메소드들이 한 클래스내에 다 존재하고 있습니다.
이러한 문제를 해결을 하기 위해서 기존 코드를 분리할 시점에 도달했습니다.