안녕하세요. 성조입니다.
이전에 작성한 SRP 포스팅에 이어서 SOLID 원칙의 두 번째 원칙. OCP에 대해서 정리해보려 합니다.
혹여나 올바르지 못한 지식 전달이 있는 경우 언제든지 피드백 댓글 남겨주시면 감사드리겠습니다.
개방-폐쇄 원칙(Open-Closed Principle, OCP)이란?
개방-폐쇄 원칙은 객체 지향 설계 원칙 중 하나로, "소프트워에 개체(클래스, 모듈, 함수 등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다."는 것을 말한다. (객체 지향 원칙에서 유명한 말이므로 공부하다 보면 들어봤을 수도 있다.)
즉, 기존 코드의 변경 없이. 새로운 기능을 추가할 수 있도록 설계하는 것을 의미한다.
[개방-폐쇄 원칙(OCP)이 적용되지 않은 예시]
public class Animal {
String animalType;
public Animal(String animalType) {
this.animalType = animalType;
}
public void move() {
if (animalType.equals("Bird")) {
System.out.println("Fly");
} else if (animalType.equals("Fish")) {
System.out.println("Swim");
}
}
}
OCP 원칙을 준수하지 않은 코드이다.
새로운 동물의 움직임을 추가하기 위해서 'Animal' 클래스의 'move' 메서드를 수정하여 조건이 충족할 수 있도록 수정해야 한다.
[개방-폐쇄 원칙(OCP)이 적용된 예시]
abstract class Animal {
abstract void move();
}
class Bird extends Animal {
@Override
void move() {
System.out.println("Fly");
}
}
class Fish extends Animal {
@Override
void move() {
System.out.println("Swim");
}
}
OCP 원칙을 준수한 코드다.
새로운 동물의 움직임을 추가하려면 추상 클래스인 'Animal' 클래스를 상속받는 새로운 클래스에서 오버라이드로 기능을 만들어서 기존 코드를 수정하지 않고 확장하면 된다.
개방-폐쇄 원칙(Open-Closed Principle, OCP) 장점과 단점
[장점]
1. 재사용성
개방-폐쇄 원칙(OCP)을 준수하면 새로운 기능을 추가하기 위해 새로운 클래스를 생성하게 된다. 이때 '새로운 클래스'라는 것은 기존의 클래스를 확장하는 것으로. 기존 클래스의 기능을 재사용하고, 새로운 기능을 추가하는 과정으로 확장한다.
2. 유지 보수성
클래스나 모듈이 수정에 대해 닫혀 있기 때문에, 기존 코드의 변경 없이 새로운 기능을 추가할 수 있게 된다. (재사용성에서 확장되는 것과 연관.)
기존 코드는 단일 책임 원칙(SRP)을 지키며, 확장에는 열려있고 원래 기능에 대한 수정은 닫혀 있기 때문에 코드를 최대한 건드리지 않는 상태에 가깝게 유지 보수할 수 있으며, 좋은 모듈화를 통해서 버그를 최소화하고 안정성을 유지하는데 많은 도움을 준다.
3. 유연성
OCP를 준수하면 새로운 요구 사항이 있을 때 확장하기 좋다. OCP 규칙 자체가 [확장은 OK, 기존 코드의 기능 수정 NO]라는 특징이 있어서 원하는 기능을 유연하게 붙이고 추가하기 좋다.
[단점]
1. 설계의 어려움과 복잡성
OCP를 잘 적용하기 위해서는 잘 설계된 아키텍처와 추상화 레벨이 필요하다. 설계(Design)를 잘못하게 되면, 추후에 코드를 리팩터링 하는 과정에서 어려움을 느낄 수 있고, OCP를 적용하는 것은 충분한 경험과 설계 능력이 필요하다. 또한, OCP를 준수하면 더 많은 클래스를 만들어야 할 수 있는데 각 클래스는 특정한 기능만을 가지고 있어야 하기 때문에 소프트웨어가 더 복잡해질 수 있다.
2. 오버 엔지니어링
모든 가능한 변경에 대해 고려하고 확장을 열어놔야 하기 때문에 높은 레벨의 추상화가 필요할 수 있다. 너무 과한 경우의 수를 예측하는 것이 될 수 있으며, 투자 대비 효율이 안 나오는 비효율적 어려움을 줄 수 있다.
오타나 궁금한 부분이 있다면 언제든지 댓글 남겨주시면 답변드릴 수 있도록 노력하겠습니다.
다음 포스팅 때 뵙겠습니다. 감사합니다.
'Java ☕ > Java' 카테고리의 다른 글
[Java] 리스코프 치환 원칙(Liskov Substitution Principle, LSP) (0) | 2023.05.31 |
---|---|
[Java] 자바 SE, EE 정리 (with ME, FX 맛보기 정리) (0) | 2023.05.30 |
[Java] 접근 지정자(Access Modifier) Private/Protected/Default/Public 정리 (0) | 2023.05.29 |
[Java] 단일 책임 원칙(Single Responsibility Principle, SRP) (0) | 2023.05.29 |
[Java] 박싱(Boxing)과 언박싱(Unboxing) (0) | 2023.05.28 |