객체지향프로그래밍

SOLID 5원칙 - OCP 개방 폐쇄 원칙(Open/Closed Principle)

쿠쿠s 2022. 1. 18. 15:08

 

소프트웨어 개체(클래스, 모듈, 함수 등등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다.

인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현하는 것이다.개방-폐쇄 원칙이 잘 적용되면, 기능을 추가하거나 변경해야 할 때 이미 제대로 동작하고 있던 원래 코드를 변경하지 않아도, 기존의 코드에 새로운 코드를 추가함으로써 기능의 추가나 변경이 가능합니다.

 

 

만약 이 원칙을 지키지 않으면 어떤일이 발생하는지 코드로 먼저 보여드리겠습니다.

 

class Car{
    String name;
    String brand;

    public Car(String name, String brand) {
        this.name = name;
        this.brand = brand;
    }

}


public class People {

    public static void main(String[] args) {

        Car K3 = new Car("k3", "kia");
        Car Avante = new Car("avante", "현대");

        rideCar(K3);
        rideCar(Avante);
    }

    public static void rideCar(Car car) {
        if(car.name.equals("k3")){
            System.out.println("k3 차량에 탑승했습니다.");
        }else if(car.name.equals("avante")){
            System.out.println("avante 차량에 탑승했습니다.");
        }else{
            System.out.println("해당 차량은 없습니다.");
        }
        return;
    }
}

출력: k3 차량에 탑승했습니다. avante 차량에 탑승했습니다.

 

이렇게 봤을 때는 문제가 없습니다. 하지만 탑승하고 싶은 차량이 늘어난다면?? 테슬라나 제네시스 등등 추가를 하고싶을때, 즉 확장을 하려할때 제한되어있는 상태이고 rideCar 메소드를 수정해야 하는 상황이 오는 수정에는 닫혀있는 OCP원칙을 위반하는 프로그래밍 입니다.

 

 

해결방법은 인터페이스를 사용하면 됩니다.

 

interface Car{
    void rideCar();
}

class K3 implements Car{

    @Override
    public void rideCar() {
        System.out.println( "K3에 탑승했습니다.");
    }
}

class Avante implements Car{
    @Override
    public void rideCar() {
        System.out.println("Avante에 탑승했습니다.");
    }
}

class Tesla implements Car{
    @Override
    public void rideCar() {
        System.out.println("Tesla에 탑승했습니다.");
    }
}

class Genesis implements Car{
    @Override
    public void rideCar() {
        System.out.println("Genesis에 탑승했습니다.");
    }
}


public class People {

    public static void main(String[] args) {
        Car K3 = new K3();
        Car Avante = new Avante();
        Car Tesla = new Tesla();
        Car Genesis = new Genesis();

        K3.rideCar();
        Avante.rideCar();
        Tesla.rideCar();
        Genesis.rideCar();

    }
}

 

출력: K3에 탑승했습니다. Avante에 탑승했습니다. Tesla에 탑승했습니다. Genesis에 탑승했습니다.

 

 

이와 같이 새로운 차량이 추가 되어도 다른 수정없이 확장만 하면 됩니다. 역할(인터페이스) 구현(인터페이스를 구현한 클래스) 분리를 해야합니다. 개방-폐쇄 원칙은 객체 지향 프로그래밍의 핵심 원칙 이라고 할 수 있고, 잘못 된 예시 코드를 봤을 때 이 원칙을 따르지 않아도 객체지향프로그래밍을 할 수 없는 것은 아니지만 객체 지향 프로그래밍의 가장 큰 장점인 유연성, 재사용성, 유지보수성을 얻을 수 없어서. 이 원칙은 반드시 지켜야할 원칙입니다.

 

 

 

 

참고 - 위키백과