thumbnail

SRP, Single Responsibility Principle<br/>

(단일 책임의 원칙)

클래스는 단 하나의 책임을 가져야 한다.<br/>
책임은 해야하는 것이다<br/>
책임은 변경의 이유이다

<br/>

#Before branch

<img alt="" src="https://static.podo-dev.com/blogs/images/2019/07/10/origin/E91LXU181224235521.JPG" style="width:470px">

AreaCalculator는 도형의 넓이값을 더해주는 연산을 하는 클래스이다.<br/>
<br/>

<br/>

AreaCalcuator.java

package com.cglee079.srp;

import java.util.ArrayList;
import java.util.Iterator;

public class AreaCalculator {
		private ArrayList shapes = new ArrayList();
		
		public void calcuate(){
				Iterator iter = shapes.iterator();
				double areasum=  0.0;
				while(iter.hasNext()){
					Shape curShape = iter.next();
					areasum += curShape.area();
				}
				System.out.println(areasum);
		}
		
		public void addShape(Shape s){
			shapes.add(s);
		}
}
<br/>

SRP 원칙은 하나의 클래스에 하나의 책임을 가지는 것을 말한다.<br/>
책임은 변경의 이유이다<br/>
위의 AreaCalculator클래스는 SRP원칙에 위배됨을 보인다<br/>
변경의 이유를 두가지 가지고 있기 때문이다.<br/>
<br/>
하나는, shape 넓이의 합을 계산하는 연산과<br/>
다른 하나는, 넓이의 합을 출력하는 출력문이다 <br/>

예를 들어, 연산이 합이 아닌 곱을 계산하는 클래스로 바꾼다 가정한다면<br/>
AreaCalculator 클래스의 코드는 변경되어야 할 것이다.<br/>
또한, 결과값의 출력문을 바꾸고자 한다면<br/>
AreaCalculator 클래스의 코드는 변경되어야 할 것이다.

이렇듯 변경의 이유를 2가지를 가지기 때문에 2가지의 책임을 가진다 할 수 있다.<br/>
(*반대로, 프로그래머가 출력문을 앞으로 절대로 안바꿀 것이라고 가정해보자,<br/>
그렇다면 위 클래스의 변경의 이유는 하나이며 하나의 책임을 가질 것이다.<br/>
그러므로 위 클래스는 SRP원칙에 위배되지 않을 것이다.)

<br/>
그렇다면 왜 클래스는 하나의 책임을 가져야 할까?<br/>
예를 들어서, 하나의 클래스가 100개의 책임을 가진다고 가정해보자<br/>
이 때, 이 클래스에 변경사항이 생긴다면<br/>
이 변경사항에 대하여 100개의 책임에 대한 모든 코드를 테스트 해야 할 것이다.<br/>
<br/>

#After branch

<img alt="" src="https://static.podo-dev.com/blogs/images/2019/07/10/origin/BQDJZL181224235521.JPG" style="width:470px"><br/>
AreaCalculator 클래스를 SRP원칙에 위배되지 않게 하기 위하여 <br/>
ConsolePrinter 클래스를 만들었다 <br/>
<br/>
책임을 분리하여<br/>
AreaCalculaotor 클래스는 연산을<br/>
ConsolePrinter는 결과 값을 받아 출력하는 책임을 가진다<br/>

AreaCalculator.java

package com.cglee079.srp;

import java.util.ArrayList;
import java.util.Iterator;

public class AreaCalculator {
		private ArrayList shapes= new ArrayList();
		private double areasum;
		
		public double getAreasum() {
			return areasum;
		}

		public void calcuate(){
				Iterator iter= shapes.iterator();
				areasum = 0.0;
				while(iter.hasNext()){
					Shape curShape = iter.next();
					areasum += curShape.area();
				}
		}
				
		public void addShape(Shape s){
			shapes.add(s);
		}
}
<br/>

출력문을 제외하였다.<br/>
이제 AreaCalculator 클래스는 계산을 하는 하나의 책임을 가진다.<br/>
ConsolPrinter가 areasum을 참조 할 수 있도록 클래스 필드로 선언하였다 <br/>
<br/>

ConsolePrinter.java

package com.cglee079.srp;

public class ConsolePrinter {
	private AreaCalculator calculator;
	
	public void setCalculator(AreaCalculator calculator){
		this.calculator = calculator;
	} 
	
	public void print(){
		System.out.println("result : " + calculator.getAreasum());
	}
}
<br/>

<br/>
ConsolePrinter는 AreaCalculator의 객체를 참조한다.<br/>
AreaCalculator get메소드를 호출하여 넓이의 값을 출력한다.

CommentCount 0
이전 댓글 보기
등록
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
TOP