[컴퓨터공학]/[소프트웨어공학]

[소프트웨어공학] SOLID - 개방 폐쇄 원칙(Open Closed Principle)

딥러닝 도전기 2022. 5. 1. 22:04

[소프트웨어공학] SOLID - 개방 폐쇄 원칙(Open Closed Principle)

 

객체 지향 설계 5원칙 SOLID

SOLID란 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 의미합니다. 대규모 프로그램에서 프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 할 때 이 원칙들을 적용해야 합니다. 다섯 가지 기본 원칙은 다음과 같습니다.

 

1. Single Responsibility Principle, 단일 책임 원칙

2. Open-Closed Principle, 개방-폐쇄 원칙

3. Liskov Substitution Principle, 리스코프 치환 원칙

4. Interface Segregation Principle, 인터페이스 분리 원칙

5. Dependency Inversion Principle, 의존성 역전 원칙


객체 지향 설계 원칙은 위의 다섯 가지 원칙의 앞글자를 따서 SOLID라고 합니다. 

이번 포스팅에서는 두 번째 원칙인 개방 폐쇄 원칙에 대해 다루도록 하겠습니다.

 


개방 폐쇄 원칙(Open Closed Principle)는 확장에는 열려있고, 수정에는 닫혀있어야 한다는 원칙입니다.

 

여기에서 확장이란 새로운 타입을 추가함으로써 새로은 기능을 추가하는 것을 의미하고, 확장에 대하여 열려있다는 말은 새로운 기능을 확장하기 위해서 잘 동작하는 기존 코드를 손대지 않고 새로운 코드를 추가하는 것만으로 가능해야 한다는 의미를 갖습니다.

 

수정은 확장이 발생했을 때 상위 레벨에 영향을 미치지 않아야 하는 것을 의미합니다.

따라서 수정에는 닫혀있어야 한다는 말은 새로 추가되는 코드 혹은 수정되는 코드는 기존 코드의 변경을 초래하지 않는다는 의미입니다.

 

개방 폐쇄 원칙은 추상화에 크게 의존합니다. 추상화된 인터페이스를 선언하고 그 인터페이스를 상속받아 구체적인 행위를 구현하여 새로운 클래스가 추가되어도 기존 코드를 손댈 필요가 없게(수정에 닫혀있도록) 구현합니다.

 

개방 폐쇄 원칙을 적용하지 않은 예제를 검색해보면 적지 않게 switch문을 발견할 수 있습니다. switch문을 사용한다는 것은 확장에 대해 닫혀있다는 것을 의미하기 때문입니다. 

 

예제를 통해 살펴보도록 하겠습니다.

 

개방 폐쇄 원칙을 준수하지 않은 코드

public class Cafe{
	public void makeCoffee(String name){
    	if(name == "아메리카노"){
        	System.out.println("아메리카노를 만듭니다");
        }
        else if(name == "라떼"){
        	System.out.println("라떼를 만듭니다");
        }
        else{
        	System.out.println("메뉴를 골라주세요");
        }
    }
}

위의 코드에서는 개방 폐쇄 원칙을 준수하지 않았습니다. 새로운 메뉴가 들어오면 클래스 자체를 수정해야하기 때문입니다. 즉, 확장에 대해 열려있지 않기 때문입니다.

 

예를 들어 새로운 메뉴인 바닐라라떼를 주문하기 위해서는 다음과 같이 클래스의 수정이 필요하기 때문입니다.

public class Cafe{
	public void makeCoffee(String name){
    	if(name == "아메리카노"){
        	System.out.println("아메리카노를 만듭니다");
        }
        else if(name == "라떼"){
        	System.out.println("라떼를 만듭니다");
        }
        else if(name == "바닐라 라떼"){
        	System.out.println("바닐라 라떼를 만듭니다");
        }
        else{
        	System.out.println("메뉴를 골라주세요");
        }
    }
}

 

이를 개방 폐쇄 원칙을 준수한 코드로 변경하기 위해서 interface를 통한 추상화를 사용합니다. 개방 폐쇄 원칙의 해결 방법은 추상화라고 보시면 될 것 같습니다.

 

개방 폐쇄 원칙을 준수한 코드

public interface CommonRecipe{
	public void makeCoffee();
}

public class Cafe implements CommonRecipe{
	private String menu = "";
    
    public void setMenu(String menu){
    	this.menu = menu;
    }
    
    public void makeCoffee(){
    	System.out.println(menu + "를 만듭니다");
    }
}

위의 코드처럼 interface를 통해 추상화한 코드를 작성하면 다음과 같이 메뉴 추가에 자유롭습니다. (확장에 열려있다 = 확장 시 클래스의 수정이 불필요하다.)

 

Cafe cafe = new Cafe();

cafe.setMenu("아메리카노");
cafe.makeCoffee();

cafe.setMenu("라떼");
cafe.makeCoffee();

cafe.setMenu("콜드브루");
cafe.makeCoffee();

cafe.setMenu("바닐라 라떼");
cafe.makeCoffee();

 

반응형