술(述)/풀이

OCP

쪼랩전사 2022. 1. 4. 21:07
728x90

정의

SOLID 중 O에 해당한다.

OCP는 Open-Closed Principle의 약자로, 개방 폐쇄 원칙이다.

코드가 확장에 대해 열려 있고, 변경에 대해 닫혀 있어야 한다는 원칙이다.

주의! 변경을 최소화하자는 말이지, 변경하지 말라는 것이 아니다. 천재가 아닌 이상에야 완벽한 추상화를 하기는 어렵다.

위반 사례

OCP를 위반하면 비슷한 if else 문 다수 존재하거나 switch 문이 존재하게 된다.

import "log"

func doSomething(op string, a, b int64) int64 {
	switch op {
	case "+":
		return a + b
	case "-":
		return a - b
	default:
		panic("panic")
	}
}

func main() {
	ret := doSomething("+", 9, 3)
	log.Println(ret)
}

위의 코드에 나중에 곱하기, 나누기 연산을 추가해야 한다면 doSomething 함수 내부를 수정해야 한다.

 

위의 코드에 굳이 OCP를 적용하고 싶다면 아래와 같아진다.

type Calculator interface {
	Calc(a, b int64) int64
}

type Plus struct{}

func (p *Plus) Calc(a, b int64) int64 {
	return a + b
}

type Minus struct{}

func (m *Minus) Calc(a, b int64) int64 {
	return a - b
}

func doSomething(op Calculator, a, b int64) int64 {
	return op.Calc(a, b)
}

func main() {
	ret := doSomething(&Plus{}, 9, 3)
	log.Println(ret)
}

위의 코드에서 곱하기 연산을 추가하려면, 곱하기 구조체를 만들고 Calculator 인터페이스만 구현해주면 된다.

적어도, doSomething 함수 내부는 변경이 일어나지 않게 된다.

마치며...

인터페이스를 정의하는 것은 매우 어렵다. 인터페이스가 너무 없으면 유연성, 재사용성, 유지보수성 등의 이점을 잃어버리고, 인터페이스를 너무 많이 사용하면 여러 이점을 얻기는 하지만 코드가 너무 길어지고, 복잡해진다.

위에서 사용한 예제 코드만 해도 그렇다. 코드 길이부터가 너무나도 길어지게 된다.

뭐든지 적당한 것이 좋다. 인터페이스의 구현체가 하나뿐인데 굳이 먼저부터 인터페이스를 만드는 허튼짓은 하지 말길 바란다.

'술(述) > 풀이' 카테고리의 다른 글

ISP  (0) 2021.12.29
SRP  (0) 2021.12.13
LSP  (0) 2021.12.10
bash 설정 파일  (0) 2021.12.05
code bloat(코드 비대화)  (0) 2021.11.24