좋은 객체지향설계의 5가지 원칙 : SOLID
- SRP : 단일 책임 원칙(single responsibility principle)
- OCP : 개방-폐쇄 원칙(Open/closed principle)
- LSP : 리스코프 치환 원칙(Liskov substitution principle)
- ISP : 인터페이스 분리 원칙(Interface segregation principle)
- DIP : 의존관계 역전 원칙(Dependency inversion principle)
SRP : 단일 책임 원칙
어떤 클래스를 변경해야 하는 이유는 오직 하나 뿐이어야 한다.
로버트 C. 마틴(밥 아저씨)
- 한 클래스(객체)는 하나의 책임만 가져야 한다.
- 하나의 책임이라는것은 모호하지만, 중요한 기준은 변경이다.
- 변경이 있을 때 파급 효과가 적어야 한다. (매우 중요)
class Calculator {
public int calculate(String operator, int firstNumber, int secondNumber) {
int answer = 0;
if(operator.equals("+")){
answer = firstNumber + secondNumber;
}else if(operator.equals("-")){
answer = firstNumber - secondNumber;
}else if(operator.equals("*")){
answer = firstNumber * secondNumber;
}else if(operator.equals("/")){
answer = firstNumber / secondNumber;
}
return answer;
}
}
다음 코드의 문제점은 뭘까?
- 첫 번째로, Calculate의 책임감이 너무 무겁다. 혼자 "+"를 연산하는 메서드, "-"를 연산하는 메서드, "*"를 연산하는 메서드, "/"를 연산하는 메서드를 전부 짊어지고 있다.
- 두 번째로, 연산 기호가 바뀌었을 때나 각 연산 과정에서 변화가 생겼을 때 다른 연산 과정에도 영향을 끼칠 수 있다.
- "/"에서 예외처리가 되지 않았다.
=> 해결 방안
- Calculate에는 사칙연산을 실행하는 메서드만 넣는다.
- 상세한 내용은 각 클래스로 구현하되, calculate 클래스에서는 각 클래스를 불러온다.
- 예외처리를 해준다.
class Calculator {
private int firstNumber;
private int secondNumber;
public Calculator(){
this.firstNumber = 0;
this.secondNumber = 0;
}
public Calculator(int firstNumber, int secondNumber) {
this.firstNumber = firstNumber;
this.secondNumber = secondNumber;
}
public int addOperation() {
AddOperation addOperation = new AddOperation(firstNumber,secondNumber);
return addOperation.operate();
}
public int subtractOperation(){
SubstractOperation substractOperation = new SubstractOperation(firstNumber, secondNumber);
return substractOperation.operate();
}
public int multiplyOperation(){
MultiplyOperation multiplyOperation = new MultiplyOperation(firstNumber,secondNumber);
return multiplyOperation.operate();
}
public double divideOperation() {
DivideOperation divideOperation = new DivideOperation(firstNumber, secondNumber);
return divideOperation.operate();
}
public void setFirstNumber(int firstNumber) {
this.firstNumber = firstNumber;
}
public void setSecondNumber(int secondNumber) {
this.secondNumber = secondNumber;
}
}
class DivideOperation{
private int firstNumber;
private int secondNumber;
public DivideOperation(int firstNumber, int secondNumber) {
this.firstNumber = firstNumber;
this.secondNumber = secondNumber;
}
public void setFirstNumber(int firstNumber) {
this.firstNumber = firstNumber;
}
public void setSecondNumber(int secondNumber) {
this.secondNumber = secondNumber;
}
public double operate(){
try{
return firstNumber/secondNumber;
} catch(ArithmeticException e){
System.out.println("0으로 나눌수 없습니다. 다시 계산해주세요");
exit(0);
}
return firstNumber/secondNumber;
}
}
Calculator와 나눗셈 영역만 업로드했다. 나눗셈은 try-catch로 0으로 나눌 때를 대비해 ArithmeticException을 걸렀고,
지금은 아니지만 혹시나 계산기 내의 메서드가 비밀이라고 할 때를 대비해 인자들을 private로 감쌌다.
의외로 try-catch문으로 감싸는걸 까먹어서 오래 걸렸다.
'설계' 카테고리의 다른 글
선형대수를 이용해 공평한 점수 설계하기 (0) | 2023.10.16 |
---|---|
PK는 왜 Long을 쓸까? (0) | 2023.02.23 |
TIL - 좋은 객체지향적 설계원칙, SOLID (0) | 2023.01.26 |
TIL - REST API : 누구나 읽기 쉽게 설계하기 (0) | 2023.01.18 |