티스토리 뷰
Photo by Austin Distel on Unsplash
Liskov Substitution Principle에 이어지는 Interface Segregation Principle을 알아보자
- Single Responsibility Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
Interface Segregation Principle
"Clients should not be forced to depend on methods they do not use." - Robert C. Martin
Segregation 은 구분, 분리라는 뜻이다.
매우 좁게 말해보자면, 함수는 써야할 변수의 값, 메서드만 인자로 받아야 한다는 것이다. 이게 무슨 의미일까?
비유를 하자면, 백엔드 개발할 수 있는 사람을 인자로 받으면 충분한데, 구글, 아마존, 넷플릭스 10년 경력자를 인자로 받지 말라는 것이다.
위 코드를 보면 (스포일러: 사실 io.Writer 인터페이스를 만족하는 녀석만 받아도 충분한데) *os.File을 받게 해두었다.
1) 애초에 파일에 쓰도록 되어 있으니, 네트워크 너머로 쓸 수 있는 가능성이 아예 배제되어 버린다.
- 나중에 네트워크 저장소에 쓸 수 있게 해달라면 낭패!
2) 바로 디스크의 파일에 써버리니, 테스트에서 확인하려면 다시 쓰여진 파일을 읽어야 할거고, 테스트가 끝나면 임시로 쓴 파일을 삭제해야 한다.
3) *os.File은 메서드가 엄청 많고, Save() 메서드와 별 상관도 없는게 대부분이다.
- 함수 Save()가 원하는 메서드를 명시할 수 있으면 더 좋을 것이다.
참고로 os.File의 다재다능한 능력을 보자
아래와 같이 io.ReadWriteCloser 인터페이스로 바꿔주면 좀 낫다
이제 *os.File 이라는 조건이 까다로운 녀석보다 훨씬 많은 놈들을 인자로 넘길 수 있다. 즉, 메서드로 Read(), Write(), Close() 가 구현되어 있는 놈들이라면 누구나!
그래도 아쉽다. 좀더 가보자.
Reader도 빼버렷! 테스트를 위해 필요하다고? 그건 다른 넘에게 맡겨!
그런데 이렇게 하면 뭔가 애매하다. 무조건 Close() 할지, 성공할때만 Close() 할지를 알 수 없다.
그럴때는 embed를 활용하면 되긴 할거다. (좀 조잡함) embed 해주고, embed 된 녀석의 Close()를 무용지물로 만드는 거다.
애초에 위 예제를 왜 들었는지는 모르겠다.
그냥 아래처럼 io.Writer만 명시하면 되지 않나? 깔끔하다!
이로써 Save() 함수는 매우 구체적인 동시에 일반적으로 원하는 파라미터를 말하게 되었다.
이미 비유를 들었지만 복습삼아서 다시 말해본다.
*os.File 타입이라고 명시한 것은, 스탠포드 나오고, 20대이면서, 수영도 잘하고, 맥주를 좋아하는 Go 개발자라고 말한 것이다.
io.Writer 타입이라고 명시한 것은, Go로 개발할 수 있는 사람이라고 명시한 것이다. 매우 구체적으로 자격요건을 말했음에도,
Go 개발을 할 수 있기만 하다면 누구든 들어올 수 있다고 이야기하는 것이다.
"A great rule of thumb for Go is accept interfaces, return structs."- Jack Lindamood
Go를 개발하다 보니 웬만하면 인터페이스를 받아서 구조체를 리턴하면 되더라!
유튜브 예제를 한 번 더 보자
유튜브 링크: https://youtu.be/AKdvlr-RzEA?t=337
코드링크(유튜브에서 제공하는 링크를 옮김)
- 문제있는 코드: https://play.golang.org/p/0rYMzwKymIm
- 문제없는 코드: https://play.golang.org/p/NdFPq7bUCbG
문제있는 코드를 보자
shape라는 인터페이스가 area(), volume() 이라는 두 메서드를 요구하는데서 문제가 발생한다
왜냐하면 square 구조체는 volume() 이라는 메서드가 필요없는데도 쓸모없는 메서드를 구현해야 하기 때문이다.
문제점을 제거한 코드를 보자
1. shape 인터페이스는 area() 메서드만을 요구한다
2. 그리고 object 인터페이스는 shape를 임베딩하고 volume() 메서드를 요구한다. 즉, area()와 volume() 두 메서드를 구현하기를 요구한다
그러니 square 구조체는 area() 메서드만 구현했고, cube 구조체는 volume() 메서드를 구현했다.
필요한 것만 구현해서 깔끔하고 아름답다.
'golang' 카테고리의 다른 글
Golang으로 Min Heap을 구현해보자 (0) | 2021.05.04 |
---|---|
SOLID in GO - Dependency Inversion Principle (0) | 2021.04.05 |
SOLID in GO - Liskov Substitution Principle (0) | 2021.04.04 |
SOLID in GO - Open/Closed Priciple (0) | 2021.04.01 |
SOLID in GO - Single Responsibility Principle (0) | 2021.03.31 |
- Total
- Today
- Yesterday
- 인텔리제이
- Shortcut
- github
- golang
- 제이펍
- 독서
- intellij
- JIRA
- API
- 잡학툰
- pool
- solid
- bun
- Bug
- folklore
- 체호프
- 클린 애자일
- agile
- 영화
- strange
- postgres
- 독서후기
- ChatGPT
- websocket
- notion
- 노션
- 2023
- go
- OpenAI
- Gin
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |