본문 바로가기

IT/SOLID 원칙

개방 폐쇄 원칙 - OCP(Open Close Principal)

개방폐쇄원칙이란 확장에 대해 개방되어 있고, 수정에 대해 폐쇄되어 있는 원칙을 의미한다.

OCP에 만족되는 설계를 하려면 변경되는 소스를 파악하고, 수정 시 영향 받지 않게 해야한다.

이를 만족하기 위해서는 인터페이스를 이용해 기능의 추상화가 이루어져야한다.

 

다음 소스는 OCP를 위배하는 잘못된 예이다. 

 

public class Sword {

    public void attack() {
        System.out.println("검으로 휘두르다.");
    }
}

 

public class Person {
    private Sword sword;
    
    public void setSword(Sword sword) {
        this.sword = sword;
    }
    
    public void attack() {
        sword.attack();
    }
}

 

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setSword(new Sword());
        person.attack();
    }
}

Person 클래스가 Sword를 받아 attack()메소드를 실행하는 간단한 소스이다.

만약 Axe 무기로 변경하고 싶으면 아래와 같이 변경해야한다.

public class Axe {

    public void attack() {
        System.out.println("도끼로 휘두르다");
    }
}

 

public class Person {

    private Axe axe;

    public void setAxe(Axe axe) {
        this.axe = axe;
    }

    public void attack() {
        axe.attack();
    }

}

무기가 새롭게 추가될 때 마다, Person 클래스가 변경되어야한다. 이는 OCP에 위배된다.

OCP에 위배되지 않으려면 변경되는 코드를 확인하고, 기능의 추상화를 해야한다.

 

public interface Weapon {

    public void attack();
}

 

public class Sword implements Weapon {

    @Override
    public void attack() {
        System.out.println("검으로 휘두르다.");
    }
}

 

public class Axe implements Weapon {

    @Override
    public void attack() {
        System.out.println("도끼로 휘두르다");
    }
}

 

public class Person {

    private Weapon weapon;

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public void attack() {
        weapon.attack();
    }
}

 

public class Main {

    public static void main(String[] args) {
        Person person = new Person();
        person.setWeapon(new Sword());
        person.attack();

        person.setWeapon(new Axe());
        person.attack();
    }
}

Weapon Interface를 생성함으로서 attack() 메소드를 추상화 하였다.

Sword, Axe 클래스는 Weapon의 attack() 메소드를 구현하고 Person클래스는 setWeapon(Weapon weapon) 메소드를 통해 무기를 착용하고 각 무기에 맞는 attack() 메소드를 실행 할 수 있다.

새로운 무기 Spear가 추가되어도 Person클래스는 수정없이 Spear무기를 착용 할 수 있다.