본문 바로가기
자바웹프로그래밍/디자인패턴(design pattern)

[SOLID 패턴] SRP (단일 책임 원칙) ,OCP(개방-폐쇄 원칙) 설명

by 디찌s 2022. 3. 22.
728x90
반응형

1.Single Resposibility Principle (단일 책임 원칙)

- 객체는 단 하나의 책임만 가져야 한다.

 

예제를 통하여 SRP를 이해해보자 먼저 아래의 2개의 함수를 보자

 

public int add (int num1,int num2){
	return num1 + num2;
}
public int print(int num){
	system.out.println(num);
}

 

위 두 함수중 add 함수는 두 수를 더한 값을 반환해주고 , print함수는 전달받은 정수를 출력해준다.

 

각각의 함수는 각자의 책임을 주어 만들었다. 이것을 합쳐서

 

public void numPrint(int num1,int num2){
	System.out.println(num1+num2);
}

 

위 처럼 함수를 하나로 만들필요는 없다.

 

이제 클래스를 이용하여 생각해 보자.

 

class Dog{
	Dog(int age,string name){
    	
    }
    
    public void bark(string name){
    	
    }
    
    public void walk(){
    
    }
    
    public void fly(){
    
    }


}

 

위 처럼 개 클래스를 만들고 개클래스의 메소드에는 짖기,걷기,날기(?) 등의 메소드가 있다.

 

여기서 짖기,걷기는 개 속성의 일부분이지만 날기는 필요가 없다. 그러므로 단일 책임 원칙을 벗어 나므로 제거해야한다.

 

개발경력이 이미 있으신분들은 아마 당연하다고 생각할것이다.


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

- 확장에 대해서는 개방 , 수정에 대해서는 폐쇄라는 디자인 패턴이다.

 

예제를 통해 OCP에 대해 이해해보자.

 

class Animal{
	public String type;
    
    Animal(String type){
    	this.type = type;
    }

}

public void bark(Animal animal){
    	if(animal.type.equlas("Dog"){
        	print("월");
        }else if(animal.type.equals("Mouse"){
        	print("찍");
        }else{
        	throw Error;
        }
    	
    }

Animal cucu = new Animal("Dog");
Animal jery = new Animal("Mouse");

 

위 처럼 Animal 클래스를 만들고

 

cucu ,jery 인스턴스를 만든뒤 bark(cucu),bark(jery)를 실행하면

 

"월","찍"이 순차적으로 출력될것이다. 

 

그러나 만약에 아래와 같이 새로운 인스턴스를 생성하고 bark()를 실행하면 어떻게될까?

 

Animal cat = Animal("Cat");
bark(cat);



Print "Error"

 

아마 위처럼 error를 출력할것이다.

 

그렇다면 다시 OCP의 정의를 생각해보자. OCP는 확장에 대해서는 개방 , 수정에 대해서는 폐쇄 라고했다.

 

지금 위처럼 새로운 type에 인스턴스를 생성하여 cat이라는 개념을 확장(extension)시키려고하니깐 에러가 발생하였다.

 

에러가 발생하지않으려면 bark 함수에 if문 분기처리를 한번더 해줘야하므로 OCP 디자인패턴에 개발에 위배가 된다.

 

그렇다면 어떤식으로 개발하여야 위배되지 않고 아름다운 코드를 만들까?

 

위와 같은 문제를 해결하기위해선 interface class나 abstract 를 만들어 해결해야한다. 즉, bark함수를 수정하지 않고 

 

새로운 type에  instance를 생성하여도 위배되지 않도록 코드를 만들어야한다.

 

abstract class Animal{
	public abstract speak(){
    	
    }

}

class Cat extends Animal{
     @Override
     public void speak(){
     	System.out.println("meow");
     }

}

class Dog extends Animal{
	@Override
    public void speak(){
    	System.out.println("bark");
    }

}

public void bark(Animal animal){
	animal.speak();
}

Cat kitty = Cat();
Dog cucu = Dog();

bark(kitty);
Dog(cucu);

 

 

위처럼 코드를 만들면 meow 와 bark가 출력될것이다. 하지만 이번에도 마찬가지로

 

새로운 동물을 추가할경우 어떻게 될까?

 

만약에 소를 추가할때 bark라는 메소드는 수정에 폐쇄적이고, 새로운 인스턴스 소를 추가할땐

 

확장엔 열려있다면 위코드는 OCP 개발원칙을 잘준수하고있는것이다.

 

 

 

abstract class Animal{
	public abstract speak(){
    	
    }

}

class Cat extends Animal{
     @Override
     public void speak(){
     	System.out.println("meow");
     }

}

class Dog extends Animal{
	@Override
    public void speak(){
    	System.out.println("bark");
    }

}

class Cow extends Animal{
	@Override
    public void speak(){
    	System.out.println("Cow");
    }

}



public void bark(Animal animal){
	animal.speak();
}

Cat kitty = Cat();
Dog cucu = Dog();
Cow 음메 = Dog();

bark(kitty);
bark(cucu);
bark(음메);

 

위코드를 실행하면 meow,bark,cow 를 출력할것이고 에러가 발생하지 않는다.

 

또한 cow 생성에대한 확장에 대해서는 열려있고 bark 메소드를 수정하지 않았으므로 수정에는 폐쇄적인것을 볼수있다.

 

 

728x90
반응형

댓글