티스토리 뷰
Photo by Austin Distel on Unsplash
SOLID는 여러 번 마주쳤지만 제대로 이해했다고는 못하겠다. 이번에는 실제 Go 코드를 통해 이해해 보려 한다. SOLID를 따르는 Go 코드는 어떤 모양이어야 할까? Dave Cheney의 발표내용을 기반으로 하여 알아보았다.
- Dave Cheney posting: https://dave.cheney.net/2016/08/20/solid-go-design
- Dave Cheney YouTube: https://youtu.be/zzAdEt3xZ1M
SOLID가 무엇인지 위키부터 찾아보자. https://www.wikiwand.com/en/SOLID
In object-oriented computer programming, SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible, and maintainable. OOP에서 이해하기 쉽고, 유지와 변경이 쉬운 소프트웨어 디자인이 되도록 하는 다섯가지 디자인 원칙의 첫문자를 딴 것이다. |
코드리뷰의 기준
경험있는 개발자라면, 코드를 보면 엉망인지 잘 짜여져 있는지 느낌이 올 것이다.
근데 이건 주관적이다.(subjective!) 좀더 객관적인(objective) 기준을 가져야 한다.
나쁜 코드란 무엇일까?
Dave Cheny의 정리를 가져와보자.
Rigid. Is the code rigid? Does it have a straight jacket of overbearing types and parameters, that making modification difficult?
- 너무 고정되어 있어서 변경하기 힘들다.
Fragile. Is the code fragile? Does the slightest change ripple through the code base causing untold havoc?
- 위태롭게 구현해서, 조금만 고쳐도 시스템 전체가 영향을 받는다.
Immobile. Is the code hard to refactor? Is it one keystroke away from an import loop?
- 의존성이 얽혀있어서 리팩터링이 어렵다.
Complex. Is there code for the sake of having code, are things over-engineered?
- 과하게 구현되었다.
Verbose. Is it just exhausting to use the code? When you look at it, can you even tell what this code is trying to do?
- 장황하고 번잡스럽다.
누가 내 코드를 보고 이렇게 부정적인 지적을 해주면 기분이 좋지 않을 것이다.
좋은 디자인은 이래야 한다는 긍정적이면서도 객관적인 리뷰를 해주면 좋겠다.
그게 바로 SOLID 이다!
- Single Responsibility Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
지금부터 하나씩 들여다보자
Single Responsibility Principle
"A class should have one, and only one, reason to change." - Robert C Martin
“Do one thing and do it well” - McIlroy (Unix philosophy)
한 가지 기능만 하게, 그걸 제대로 하게 구현하자는 거다. 그러면 그 기능을 수정할 필요가 있을 때에만 수정하면 된다.
이러한 작고 날카로운 기능의 도구들을 조합해서 애초에 만든 사람도 상상 못한 큰 기능을 수행할 수도 있다.
Coupling & Cohesion - 결합과 응집?
coupling은 하나 변경하면, 다른것도 변경해야 한다는 것이다. 좋은 게 아니다.
cohesion은 떨어져 있지만 관련이 있다는 것이다. 서로 끌린다고 할까? 관련이 있으면 가까이 붙어 있는게 좋다.
Go code example
아래 링크에 정리가 잘 되어 있다.
참고 링크: https://medium.com/@felipedutratine/solid-single-responsibility-principle-in-golang-dc4a6be9bb3a
class를 struct로 바꿔서 이야기하면 struct가 오직 하나의 responsibility만을 가져야 한다는 것이다.
이를 체크해보려면 아래 세 가지를 챙겨보면 된다.
1. 구조체의 메서드가 구조체와 관련이 있는 행위인가?
- 아래 예제로 보면 book의 title을 알아내는 건 구조체와 관련이 있는 행위이지만
- book을 저장하는건 관련이 있는 행위라고 보기 어렵다. 이런 경우 별도의 구조체와 메서드로 분리시켜야 하는 것이다.
- 하나의 구조체에 하나의 기능. Single structure single responsibility
2. 구조체가 다른 구조체와 단단하게 결합(tightly coupled) 되어있나?
- 느슨하게 결합(loosely-coupled)되어 있어야 한다. 결합도가 낮을 수록 좋다
- BookToFile 이나 BookToDB 구조체의 Save() 메서드를 변경한다 하여도 Book 구조체나 구조체의 GetTitle() 메서드는 변경할 필요가 없다
3. 메서드를 다르게 적용할 수 있나?
- 만약 Book 구조체의 메서드로 Save()를 구현했다면 어떨까?
- 아마도 어디에 저장할지를 인자로 받거나, SaveToFile, SaveToDB와 같이 여러 개의 메서드를 따로 구현해야 했을 것이다.
- 하지만 SRP에 입각해서 각각의 다른 구조체의 역할로, 아래와 같이 구현하면 문제가 해결된다.
코드 링크: https://play.golang.org/p/Js1PwFo1X6j
Go code example 2
반복 학습 삼아서 또 다른 예제를 살펴보자. 미묘하게 다르다.
참고 YouTube 링크: https://youtu.be/AKdvlr-RzEA
1. Circle 구조체의 메서드인 area()는 너무(?) 많은 일을 한다. 면적 계산도 하고, 출력도 해준다.
2. Square 구조체의 구현을 들여다보자.
- name() 과 area()라는 메서드를 가지고 있다. 둘다 Square와 밀접한 관계가 있음을 알 수 있다.
- Shape 인터페이스를 만족하려면 name(), area() 메서드를 구현한 녀석이어야 한다.
- Outputter 라는 구조체가 있는데 이건 Shape라는 인터페이스를 만족하는 인스턴스를 인자로 받는다. 바로 Square 구조체가 이를 만족한다.
- Outputter는 Text(), JSON() 이라는 메서드가 있다. Outputter, 출력하는 녀석이라는 이름에 딱 걸맞게 Text로 또는 JSON 형태로 출력을 해준다.
코드 링크: https://play.golang.org/p/WDcBlmOH3W1
다음 포스팅에서는 Open/Closed Priciple을 알아보자
'golang' 카테고리의 다른 글
SOLID in GO - Liskov Substitution Principle (0) | 2021.04.04 |
---|---|
SOLID in GO - Open/Closed Priciple (0) | 2021.04.01 |
Go HTTP server를 GitHub Action을 이용해 Heroku로 deploy 해보자 (0) | 2021.03.29 |
Golang - http.Client에 context 패키지를 쓰면 더 좋다 (0) | 2021.03.05 |
Golang - http.Client에는 Timeout이 들어가야 한다. (0) | 2021.03.04 |
- Total
- Today
- Yesterday
- notion
- OpenAI
- 독서후기
- 노션
- intellij
- pool
- JIRA
- Gin
- 2023
- github
- golang
- Shortcut
- 체호프
- postgres
- ChatGPT
- 제이펍
- 독서
- bun
- solid
- 잡학툰
- strange
- 인텔리제이
- agile
- Bug
- websocket
- 클린 애자일
- API
- 영화
- folklore
- go
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |