서론
이번 글에서는 개방 폐쇄 원칙(OCP)에 대해 알아볼려한다.
바로 알아보자 :)
객체지향 설계 5대 원칙
- SRP(Single Responsibility Principle): 단일 책임 원칙
- OCP(Open Closed Priciple): 개방 폐쇄 원칙
- LSP(Liskov Substitution Priciple): 리스코프 치환 원칙
- ISP(Interface Segregation Principle): 인터페이스 분리 원칙
- DIP(Dependency Inversion Principle): 의존성 역전 원칙
OCP(Open Closed Priciple) - 개방 폐쇄 원칙이란?
확장에는 열려있으나 변경에는 닫혀있어야 한다는 원칙이다.
이것이 무슨말일까 ?
우선 여기서 말하는 확장과 변경에 대해 알아보자.
확장
새로운 타입을 추가함으로써 새로운 기능을 추가(구현)할 수 있다.
따라서 확장이 열려있다는 말은
새로운 타입(클래스, 모듈, 함수)을 추가함으로써 기능을 확장시키는 것을 말한다.
변경
확장이 발생했을 때 상위 레벨이 영향을 미치지 않아야 하는 것을 말한다.
따라서 변경에는 닫혀있어야 한다는 말은
확장이 발생했을 때 해당 코드를 호출 하는 쪽에서 변경이 발생하지 않는 것을 말한다.
이 원칙을 지키기위한 구현 방법은 ?
1. 확장 될 것과 변경을 엄격히 구분한다.
2. 이 두 모듈이 만나는 지점에 인터페이스를 정의한다.
3. 구현에 대한 의존보다는 정의된 인터페이스를 의존하도록 코드를 작성한다.
4. 변경이 발생하는 부분을 추상화하여 분리한다.
이것으로 얻는 효과는 무엇일까 ?
객체지향의 장점을 극대화 시켜주며 그 효과 중 재사용 가능한 코드의 관리를 보다 더 용이하게 만들 수 있다.
예제
OCP 원칙 위배 !
package jeongkyun.tistory.solid.ocp;
public class Driver {
public static void main(String[] args) {
// 트럭 운전 인스턴스 생성
Truck driver1 = new Truck();
driver1.drive();
//버스 운전 인스턴스 생성
Bus driver2 = new Bus();
driver2.drive();
}
}
class Truck{
public void drive() {
System.out.println("Truck Drive");
}
}
class Bus{
public void drive() {
System.out.println("Bus Drive");
}
}
위의 예제에서 운전자의 차 종이 바뀔때마다 운전자는 새로운 drive()를 실행해야한다. 이러한 문제를 ocp원칙을 이용하여 구현하면 아래와 같다.
OCP 원칙 적용 후 ↓
package jeongkyun.tistory.solid.ocp;
public class Driver {
public static void main(String[] args) {
Car[] driver = new Car[2];
driver[0] = new Truck();
driver[1] = new Bus();
for (int i = 0; i < driver.length; i++) {
driver[i].drive();
}
}
}
class Car{
public String carType = "";
public void car(String carType) {
this.carType =carType;
}
public void setCarType(String carType) {
this.carType =carType;
}
public void drive() {
System.out.println(carType + " Drive");
}
}
class Truck extends Car{
public Truck() {
setCarType("Truck");
}
@Override
public void drive() {
super.drive();
}
}
class Bus extends Car{
public Bus() {
setCarType("Bus");
}
@Override
public void drive() {
super.drive();
}
}
위와 같이 ocp의 확장은 열어주고 변경은 닫아준다는 개념을 이용하여
Car라는 클래스에서 drive()를 선언해준 다음 어느 차종이 와도 drive를 오버라이딩을 이용하여 재 정의하여 사용할 수 있도록 만들어주었다.
이렇게 만들어준다면 Car라는 클래스의 코드는 변경되지 않고 여러 차종의 drive()기능을 확장할 수 있는 관계가 만들어진다.
마치며..
SOLID원칙을 고려하여 설계하는것을 잘해야 추 후 어떠한 작업을 하더라도 유연한 솔루션을 만들 수 있다고 한다. 그러하여 해당 개념들을 하나씩 장황하게 예제도 만들어보고 하고있다. 이러한 작업들이 나중엔 나에게 큰 도움이 되길 바란다.
ps.
위의 예제들을 고심끝에 만들어보았는데
OCP의 개념과 엇나가는 부분이 있다면 댓글로 피드백 부탁드리겠습니다.
'Programming > Java' 카테고리의 다른 글
[Java] SOLID - 인터페이스 분리 원칙 (ISP / Interface Segregation Principle)이란? (개념/ 예제) (0) | 2022.05.12 |
---|---|
[JAVA] SOLID - 리스코프 치환 원칙 LSP(Liskov Substitution Principle) (1) | 2022.05.08 |
[JAVA] SOLID - 단일 책임 원칙 SRP(Single Responsibility Principle) (3) | 2022.03.11 |
[JAVA] 문자열을 Reverse 하는 방법 (0) | 2022.03.11 |
[JAVA] StringBuilder란? (개념 / 사용 이유 / 클래스 라이브러리 만들기 / 예제) (0) | 2022.03.08 |
댓글