-
안전한 코드 확장을 위한 OCP 원칙의 중요성에 대해Design Pattern 2024. 2. 4. 22:11
특정 프로젝트를 오랫동안 작업하다 보니 기능추가가 되면 어떻게 코드를 작성해야 할지 예상이 된다.
그러나 어떻게 코드를 작성해야 할지 예상이 되지 않는 경우가 있다. 최근에 제공되는 서비스에 일부만 제공해야만 하는 작업이 있었다. 일부만 제공하기 위해서는 서로 의존성으로 묶여있는 부분들을 제거하고 제공해야 하는데, "어떻게 작업해야 사이드 이슈 없이 안전하게 그리고 빠르게 작업을 진행할 수 있을까?" 고민하며 정리한 내용을 공유해보고자 한다.
안전하게 소스를 분리하기
소스를 안전하게 분리한다는 것. 좋다. 서비스를 분리하기 위해서는 기존의 로직들을 더체크해서 분리를 해야 한다. 그러나 문제는 서비스를 분리함으로써 기존에 잘 동작하던 기능도 확인해야 한다. 왜냐하면 분리라는 게 기존에 서비스에도 수정이 있기 때문이다. 이게 가장 큰 문제인데. 생각 지도 못한 영역에서 동작하지 않게 되는 경우가 있다.
QA : 여기는 기획이 추가되거나 작업영역이 아닌데?
기획자 : 저희는 여기가 수정되는 게 아니라 신규서비스인데. 왜 기존 것이 안되나요?
개발자 : 별문제 없겠지? 신규 작업하느라 바쁘니까 나중에 확인하면 돼. (나중에 까먹음...)
소스를 분리하게 되면, 기존 영역에 문제가 있다는 것을 기획자도, QA도 모른다. 심지어 개발자도 모르는 경우가 많다. 별문제 없겠지 하면서 넘기거나, 그거 말고도 확인해야 하는 게 산더미 같이 쌓여있기 때문이다. 개발 기한을 맞추려다가 까먹고 배포되고 알게 되는 경우가 종종 있다.
얼렁뚱땅 나만의 해답 - 분리가 아닌 복제
멘토 개발자 : 기존의 제공되는 소스는 그대로 둬~. 잘 동작하잖아~
신입 개발자 : 이번에 기능을 제공하려면 무조건 소스를 분리해야 하는 거 아닌가요?
멘토 개발자 : 맞아. 분리처럼 복제하는 거야. 기존의 소스에서 사용하는 영역만 복제하는 거지.
기존의 소스를 건드는 건 좀 위험한 행위이다. 기존에 잘 동작하던 게 갑자기 동작 안 할 수 있기 때문이다. 그러면 어떻게 하는 게 좋을까? 앞에서 보았지만 기존의 소스는 그대로 두고 똑같은 소스를 복사하는 것이다. 분리해야 할 소스를 복제해서 제공하는 것이다. 그런데 이렇게 되면 같은 소스가 두벌이 되니 수정을 두 번 해야 해야 하는 문제가 있다. 하지만 안전한 배포와 빠른 서비스 제공을 위해서라면 어쩔 수 없이 복제해서 나가야만 한다.
그래서 OCP가 중요한가?
SOLID의 2번째 원칙인 OCP(Open-Closed Principle)이 떠올랐다. ‘OCP는 확장에는 열려있고 수정에는 닫혀 있어야 한다’는 원칙이다. 기존의 소스가 OCP가 잘 지켜지고 있었다면 완전 다 복제할 필요는 없다. 확장에 용이하게 되어있으니까 말이다. 어떻게 보면 위에서 말한 분리가 아닌 복제를 해야 한다. 즉 수정이 아닌 확장을 해야 한다는 의미이다. 확장하기에 좋은 구조일수록 중복은 없을 것이다.
예를 들어보자
홈쇼핑 사이트를 만드는데 특정 회사에서 제품에 대한 채팅만 따로 분리해서 제공해야 하는 경우라 가정해 보자
class Product { construtor(){ this.stream = new Stream(); this.chat = new ChatSocket(); } start(){ this.stream.start(); this.chat.connect(); } }
여기서 채팅만 따로 쓰고 싶은 상황이다. 당신이라면 어떻게 하겠는가?
class Product { construtor(){ this.stream = new Stream(); this.chat = new ChatSocket(); } start(){ // 새롭게 추가되는 티스토리 회사에서 채팅만 붙게한다. if( location.href === 'tistory.com'){ this.chat.connect(); }else { this.chat.connect(); this.stream.start(); } } }
별문제 없어 보이지만, 티스토리 회사의 href값이 바뀌게 된다면? 100% 문제가 된다.
class Product { construtor(){ this.stream = new Stream(); this.chat = new ChatSocket(); } start(){ this.stream.start(); this.chat.connect(); } } // 신규 프로덕트 chat을 만들자 class ProductChat { construtor(){ this.chat = new ChatSocket(); } start(){ this.chat.connect(); } }
기존의 소스는 그대로 두고 신규 서비스에 사용하는 클래스를 새로 만들어서 제공했다. 바로 OCP 원칙이다. 수정은 없이 확장하는 것.
결론
수정보다는 확장을 말하는 OCP 원칙이 매우 중요함을 느낀다. OCP 원칙을 잘 지킬 수 있는 코드가 좋은 소스코드이며, 어떤 코드가 OCP 즉 확장에 유리한 소스코드인지 알 수 있어야 한다. 그러니까 우리는 수정하기 전에 확장할 수 있는 방법이 있는지 먼저 고민해 보는 습관을 가지자!
728x90'Design Pattern' 카테고리의 다른 글
Factory Method Pattern(팩토리 메서드) (0) 2021.09.29