본문 바로가기

Java/Methodology

[SOLID] 객체지향 설계 5원칙 - OCP

  • OCP (Open Closed Principle) 개방 폐쇄 원칙

자신의 확장에는 개방되어 있고, 주변의 변화에 대해서는 폐쇄되어 있어야한다.
소프트웨어는 확장에 대해서는 개방되어야 하지만, 변경에 대해서는 폐쇄되어야 한다. - 로버트 C. 마틴

글로는 이해하기 힘들다. 개방 폐쇄의 원칙을 지키지 않고 있는 코드를 살펴보자.

public class 아반떼
{
    public void 앞으로간다() {}
    public void 뒤로간다() {}
}

public class 쏘나타
{
    public void 앞으로간다() {}
    public void 뒤로간다() {}
}

public class 사람
{
    private 아반떼 차량 = new 아반떼();
}

만약 클라이언트인 사람이 차량을 바꾸게 된다면 코드가 어떻게 변경이 될까?

public class 사람
{
    private 쏘나타 차량 = new 쏘나타();
}

이렇게 차량이 바뀔때마다 코드가 수정이 되어야한다.
그러면 어떻게 수정을 해야 변화에 폐쇄될 수 있을까?

interface 차
{
    void 앞으로간다();
    void 뒤로간다();
}

public class 아반떼 implements 차 
{

    @Override
    public void 앞으로간다() {}
    @Override
    public void 뒤로간다() {}

}

public class 쏘나타 implements 차 
{

    @Override
    public void 앞으로간다() {}
    @Override
    public void 뒤로간다() {}

}

public class 사람
{

    private 차 차량 = new 아반떼();

}

이렇게 중간에 interface를 두어 구현체가 아닌 인터페이스에 의존하게 하면된다.

그렇다면 이렇게하면 정말로 사람은 주변의 변화에 폐쇄되어 있는가 라는 의문을 가져야한다.
아직 아반떼라는 구현체가 코드에 자리잡고 있기때문이다. 아직도 구현체가 바뀌면 클라이언트의 코드가 수정이 되어야한다.

다시 한번 코드를 수정해보자

public class 사람
{
    private final 차 차량;
    public 사람(차 차량)
    {
        this.차량 = 차량;
    }
}

이제 사람을 사용하는 쪽에서 차량을 주입해주기만 하면 된다. (DIP 까지 설명하게 될 것 같아서 더 이상의 설명은 DIP 부분에서 계속한다.)

사람이 차량을 변경하더라도 클라이언트인 사람의 코드는 전혀 변경될 필요가 없다.(폐쇄)
차량의 종류가 많아지더라도 사람을 사용하는 쪽에서 주입하기 때문에 클라이언트는 차량의 확장에 열려있다.(개방)

OCP, DIP 관련해서 자세한 내용은 Spring & JPA 카테고리에서 자세하게 다룰 예정이다.