SRP 원칙에 이어서 개방 폐쇄 원칙인 OCP(Open Closed Principle)에 대해서 알아보도록 하겠습니다.
개방 폐쇄 원칙(OCP)의 이해와 예제
개방 폐쇄 원칙이란
소프트웨어 개발 작업에 이용된 많은 모듈 중에 하나에 수정을 가할 때 그 모듈을 이용하는 다른 모듈을 줄줄이 고쳐야 한다면, 이와 같은 프로그램은 수정하기가 어렵습니다. 개방-폐쇄 원칙은 시스템의 구조를 올바르게 재조직(리팩토링)하여 나중에 이와 같은 유형의 변경이 더 이상의 수정을 유발하지 않도록 하는 것입니다. 개방-폐쇄 원칙이 잘 적용되면, 기능을 추가하거나 변경해야 할 때 이미 제대로 동작하고 있던 원래 코드를 변경하지 않아도, 기존의 코드에 새로운 코드를 추가함으로써 기능의 추가나 변경이 가능합니다.
2023.05.26 - [개발/개발 공통] - [객체지향 SOLID 원칙] 단일 책임 원칙(SRP)의 이해와 예제
인터페이스를 추가하여 다형성을 활용하는 것이 가장 대표적인 예입니다.
예제
아래와 같이 greet 이라는 인사와 관련된 클래스의 예제를 봅니다.
hi라는 내부 string에 따라 상황에 맞는 인사를 return 하도록 한 예제입니다.
만약 지속적으로 인사 예제가 추가되는 경우 Greet이라는 클래스가 계속 수정되고 테스트되어야 합니다.
지금 예제는 다소 단순하고 가독성이 나쁘지 않긴 하지만 조금 크거나 내가 잘 모르는 클래스에 기능을 추가해야 한다고 생각하면 조금 불편해 보입니다.
이런 경우 OCP 의 원칙을 위반한다고 볼 수 있고 인터페이스를 통해 개선해 볼 수 있습니다.
#include <iostream>
using namespace std;
class Greet {
public:
string greet() {
if (hi == "morning") {
return "Good morning";
}
else if (hi == "casual") {
return "What up";
}
else {
return "Hi";
}
}
void setHi(string _hi) {
hi = _hi;
}
private:
string hi;
};
sayHi 하는 인터페이스 클래스를 추가하였습니다.
Greet 클래스는 sayHi 인터페이스에만 의존하여 say 만 호출합니다. (의존성 역전 원칙과도 연관됩니다.)
실제 각 상황별 say는 각 클래스 객체는 sayHi 인터페이스를 구현하고 say를 수행합니다.
#include <string>
#include <iostream>
using namespace std;
class sayHi {
public:
virtual string say() = 0;
};
class Morning : public sayHi {
public:
string say() override {
return "Good morning";
}
};
class Casual : public sayHi {
public:
string say() override {
return "What up?";
}
};
class Default : public sayHi {
public:
string say() override {
return "Hi";
}
};
class Greet {
public:
string greet() {
return hi->say();
}
void setHi(sayHi* _hi) {
this->hi = _hi;
}
private:
sayHi* hi;
};
테스트는 아래와 같습니다.
Greet을 하나 생성하고 setHi를 통해 원하는 종류의 인사를 주입시켜 줍니다.
이후 greet() 을 호출해주기만 하면 각 상황에 맞는 인사가 return 됩니다. 지금의 경우 Morning을 할당했으므로 Good morning이 반환되어 테스트가 성공함을 알 수 있습니다.
TEST(Hi, HiTest) {
Greet* g = new Greet();
g->setHi(new Morning());
EXPECT_EQ(g->greet(), "Good morning");
}
결론
객체지향에서 기존 절차지향과 가장 다른 것이 이 다형성과 관련된 것이라고 생각합니다. 인터페이스, Override를 활용하여 기능 추가를 쉽게 만들고 기존 코드에 영향을 최소화하는 방식은 규모가 커지거나 의존성이 커지는 프로젝트에 매우 필수적인 요소라고 할 수 있을 것입니다.
'개발 > 개발 공통' 카테고리의 다른 글
[객체지향 SOLID 원칙] 인터페이스 분리 원칙(ISP)의 이해와 예제 (0) | 2023.05.26 |
---|---|
[객체지향 SOLID 원칙] 리스코프 치환 원칙(LSP)의 이해와 예제 (0) | 2023.05.26 |
[객체지향 SOLID 원칙] 단일 책임 원칙(SRP)의 이해와 예제 (0) | 2023.05.26 |
좋은 코드 개발 문화 (클린 코드, 코드 리뷰, TDD) (0) | 2023.05.22 |
[ChatGPT] 챗GPT 가입, 사용법 및 활용 팁 정리 (0) | 2023.03.01 |