변경에는 닫혀있지만 확장에는 열려있다
백엔드 개발자라면 코드를 작성할 때 기존의 코드를 변경하지 않으면서, 기능을 원할때 언제든지 추가할 수 있도록 코드를 설계해야한다라는 말을 들어본 적이 있을 것이다.
객체지향의 개발 원리(SOLID) (다른 말로 소프트웨어 설계 기법) 중 하나로 이번 글에서는 OCP에 대해 설명해보고자 한다
SOLID 설계 원칙은 oop의 4가지 특징(추상화, 상속, 다형성, 캡슐화)와 더불어, 객체 지향 프로그래밍의 단골 면접 질문 중 하나이다. 또한 앞으로 자주 마주칠 디자인 패턴(Design Pattern)들이 SOLID 설계 원칙에 입각해서 만들어진 것이기 때문에 SOLID 설계원칙에 대해서 잘 알아야한다
OCP 는 쉽게 말해 추상화라고 생각하면 편하다
추상화란 다른 모든 종류의 객체로부터 식별될 수 있는 객체의 본질적인 특징
추상화와 인터페이스와는 밀접하게 관련되어있다
아래 코드를 통해 자세히 살펴보자
인터페이스
// Interface
public interface IService {
String test();
}
구현체
@Service
public class AServiceImpl implements IService {
@Override
public String test() {
return "AServiceImpl";
}
}
컨트롤러
// Controller
@RequiredArgsConstructor
@RestController
public class SampleController {
private final IService service;
@GetMapping("/test")
public String test(){
return service.test();
}
}
위 예시 코드를 보면 컨트롤러는 특정 구현체가 아닌 IService 타입을 의존 주입받고 있다
특정 구현체인 AServiceImpl 을 의존주입 받아도 괜찮다
이제 인터페이스를 구현하는 다른 구현체 BServiceImpl를 추가해보자
public class BServiceImpl implements IService {
@Override
public String test() {
return "BServiceImpl";
}
}
AServiceImpl 와 마찬가지로 IService에 선언된 test() 메서드를 구현하고 있다 이제 이 클래스에 @Service 어노테이션을 붙이면 스프링 컨테이너에 의해 SampleController 로 의존주입이 된다
BServiceImpl로 내용을 구현하고 싶으면 AServiceImpl 의 @Service 어노테이션은 제거해주어야 한다.)
이렇게 구현체가 아닌 인터페이스를 의존받으면 OCP 원칙을 지킬 수 있다.경우에 따라서 원하는 구현체로 바꿔칠 수 있는 것이다.
이렇게 설계하는 것이 올바른 소프트웨어 원칙이라고 한다.
소프트웨어는 하드웨어랑 달리 이름에서부터 말랑말랑 하다. 말랑말랑하게 설계하기 위해서는 변경에는 열려있고 확장에는 닫혀있는 객체 지향적인 코드를 작성해야할 것이다.
앞으로 이런 태도를 가지고 코드를 대하고 끊임없이 객체 지향적인 사고를 위해 고민해봐야겠다
https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99-SOLID
https://junior-datalist.tistory.com/243