728x90

객체지향 5 원칙이라해서 프로그램이 견고하며 고치기 쉬운 상태가 된다는 뭐.. 그런 거다.

그런데 이 원칙을 막상 실제 프레임워크를 이용하는, 예컨데 스프링 부트에서 적용하려고 한다면 막막하거나 그런 코드를 본 적이 없지 않은가?

나는 이런 느낌을  이벤트 관련 서비스 개발을 맡았을  때 느꼈다. 첫 번째는 기간 내 1회 참여였으나 이후 1일 1회 참여도 가능하냐는 요건이었다. 처음 코드와 테이블 설계 자체가 기간 내 1회 참여였기에 곤란하다는 느낌도 있었다. 하물며 2가지 요구사항이 시간을 두고 들어와서 기존 코드를 고치는 데 겁이 났었다.

하지만 이 문제는 간단하게 Api의 로직 내 If문 추가로 끝난다.

그 이후 요건이 또 들어왔다. 원래 이벤트 참가 시 참가 기록 및 쿠폰 발급이있다. 새로운 기능인 참가 기록만 하는 경우도 필요해졌다.

이런 식으로 하나의 서비스에 여러가지 목적이 담긴 코드가 섞이면서 의도가 불명확해지고 난잡해졌다.

그렇다면 의도가 명확해지고 코드가 간단해지는 방법은 없을까?

하지만 코드가 간단해지면서 한번에 되는 마법이란 없다. 모든 로직에 대한 코드는 어딘가에 있어야 한다는 사실을 잊지 말자 그렇기에 결국 Solid는 난잡한 방을 정리하는 정리법에 불과하다는 생각이 든다.

각 추상화 방식에는 방법과 목적이 있을 것이다. 각 의미를 생각해보자.

1. 인터페이스의 의미
스프링을 배우면 서비스는 인터페이스를 사용하라는 말을 하지만 인터페이스와 구현체가 1 대 1로 매핑되게 사용하는 경우가 흔하지 않나?

애초에 인터페이스는 무엇일까?

인터페이스를 설계서란 이야기를 많이 하지만 그게 옳은 표현일까?
설계서를 생각한다면 나는 레고 설계서가 생각이 나는데 꽤 두껍고 복잡했던 것으로 기억이 난다. 그래서인지 인터페이스를 만들 때에도 그런 두꺼운 레고 설계서를 만드는 경향이 있다는 것을 관찰했다.

코드에서 말하는 설계서는 객체에 대한 설계서, 즉 작은 부품에 대한 설계서를 일컫는 것이기에 다중 구현이 가능하도록 코드에서 지원해준다.

그렇다면 이벤트 서비스에는 어떤 기능이 들어가야 할까?

2. 추상 클래스와 추상 메소드
스프링 부트에서 추상 클래스를 써보았나? 그런 경험이 없다. 그리고 이게 가능한가? 보통 인터페이스만 사용했으니 더 그러하다. 추상 클래스는 무엇일까?

3. 상속과 구현
상속은 부모 클래스의 속성과 메소드를 자식 메소드가 사용할 수 있게 된다. 즉, 속성과 기능이 복제가 된다. 다른 언어에서는 다중 상속도 구현해주나 자바에서는 다중 상속을 지원하지 않는다.
구현은 인터페이스의 메소드 시그니처만 가지고 기능을 만들어야 한다.

4.추상 메소드와 디폴트 메소드
추상 클래스는 추상 메소드를 만들 수 있다. 인터페이스는 디폴트 메소드를 자바 8부터? 지원해주고 있다. 두 개의 차이는 무엇일까?

4. 스프링 빈과 공통 로직
빈으로 등록되는 객체는 싱글톤의 성격을 띄게 되는데, 빈을 의존성 주입을 받아서 사용하게 된다. 그러니까 인터페이스의 디폴트 메소드는 빈에 접근하려면 파라미터로 받을 수 밖에 없다.
반면 추상 클래스는 해당 빈을 변수로 가져갈 수 있다.

5. 동일한 인터페이스를 가지는 서비스가 많아지면 빈의 싱글톤 개념이 깨지게 된다. 그렇기 때문에 각 서비스에 빈 이름을 고유하게 설정해 줘야한다.

6. 웹 프로젝트의 경우 모든 입력은 Controller에서 온다. 그렇기 때문에 해당 서비스를 불러오는 방법을 어느 곳에 두냐에 따라서 코드가 더러워지는 곳을 정할 수 있다.

1. 필터 2. 컨트롤러 3. 서비스

코드를 적거나, 보기 좋게 적고 싶지만 그럴 시간이 없다.
시간이 날 때 막 적어둔 이 글을 풀어서 예시를 하나씩 적으면서 정리해보려고 한다.

이 글은 solid와 di, 난잡해지는 코드를 보며 생각했던 넋두리를  담은 글이다.

반응형

+ Recent posts