OOP란 뭔가? 객체 중심으로 사고한다는 그런 개념적인 풀이 말고, OOP의 핵심 개념인 추상화, 캡슐화, 다형성, 상속 네 가지 개념을 짬통하면 뭐가 나오는지 감이 올듯 말듯 해서 정리하는 글이다.

예시1) DI + 인터페이스 (추상화, 다형성)

스프링은 Controller Service Repository 세 계층으로 나뉘어 있는데, 보통 서비스는 리포지토리를 인터페이스 타입으로 받아 사용하라고 가르친다. (예시2에 후술) 아래 예시는 DI와 함께 인터페이스에 의존함으로써 서비스 레이어와 리포지토리 레이어를 느슨하게 결합한 사례이다.

public interface Repository {
	public Response save(Request request);
}

@RequiredArgsConstructor
public class InmemoryRepository implements Repository {

	private final Map<String, String> store = new HashMap<>();

  @Override
  public Response save(Request request) {
      store.put(request.getKey(), request.getValue());
      return new Response("Inmemory 저장 완료");
  }

}

@RequiredArgsConstructor
public class JdbcRepository implements Repository {

  private final DataSource dataSource;

  @Override
  public Response save(Request request) {
		 // jdbc 통신 코드
		 return new Response("db 저장 완료");
  }
}

@Service
@RequiredArgsConstructor
public class Service {

	private final Repository repository;
	
	public String save() {
	
		repository.save();
	
	}
}

서비스가 내부 구현을 전혀 모르게 되면 다음 이점이 생긴다.

설정 파일에서 인메모리 저장 클래스를 사용하든, Jdbc 저장 클래스를 사용하든 서비스 클래스는 한 줄 변경없이 그대로 동작한다(DI가 없었다면 new() 한 줄은 수정 필요). 앞으로도 여러 구현체를 추가할 수 있고(확장에 열려있음) 목킹이 가능하므로 테스트에도 용이하다.

예시2) 프록시 (상속, 다형성)

대부분 우리는 스프링 빈을 등록할 때 아래와 같이 new 키워드를 사용한다.

@Bean
public ExampleBean exampleBean() {
	return new ExampleBean();
}