
클래스 -> 클래스, 인터페이스 -> 인터페이스 단일 상속 시 extends 키워드 사용
인터페이스 -> 클래스, 상속 시 implements 키워드 사용 (구현 필요)
관심사의 분리
- 인터페이스와 로직의 분리
- 역할을 명확하게 하여 낮은 결합도 달성

서비스와 리파지토리의 연결성을 끊어낼 수 있는 방법 (관심사의 분리)
아래 예제는 DB등 다른 저장소로 변경 시, 즉 기능 확장 시에 코드가 변경되므로 OCP를 위반,
또한 구현체를 인터페이스가 아닌 서비스 클래스가 직접 설정하므로, DIP를 위반
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository = new TempMemberRepository();
}
외부에서 구현체의 의존관계 주입(DI)에 집중하는 AppConfig 클래스
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new TempMemberRepository();
}
구현체의 실행에 집중하는 변경된 MemberServiceImpl 클래스
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
스프링 컨테이너(ApplicationContext)에 등록된 Bean을 가져와 다음과 같이 사용 (IoC)
//AppConfig appConfig = new AppConfig();
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
// DI, IoC
MemberService memberService =
applicationContext.getBean("memberService", MemberService.class);
Member member = new Member(1L,"A", Grade.MEMBER);
memberService.join(member);
SOLID 원칙중 DIP, OCP
DIP(Dependency Inversion Principle) : 의존 역전 원칙
상위 모듈은 하위 모듈의 구현에 의존해서는 안 되며, 하위의 모듈이 상위 모듈에 정의한 추상화에 의존 해야한다는 원칙
구현과 역할의 분리, 클래스(구현)에 의존하지 않고, 인터페이스(역할)에 의존
인터페이스에 의존함으로서, 확장이 가능하고 변화에는 폐쇄적인 OCP도 만족
OCP(Open Closed Principle) : 개방 폐쇄 원칙
자신의 확장에는 열려있어야 하고, 주변의 변화에는 닫혀있어야 한다는 원칙
요구사항 변경시 기존 요소는 수정이 일어나면 안되며, 확장을 통한 재사용이 가능해야함