Tucker의 Go 언어 프로그래밍 Ch27 ~ Ch30
이 글은 골든래빗 《 Tucker의 Go언어 프로그래밍 》의 27장~30장 써머리입니다.
Ch27 ~ Ch30
- 객체지향 설계 원칙 SOLID
- 테스트와 벤치마크
- Go로 만드는 웹서버
- RESTful API 서버 만들기
# 객체지향 설계 원칙 SOLID
좋은 설계를 위해 결합도를 낮추고 응집도를 높일 수 있는 원칙
- 결합도 ⬇️
- 모듈이 서로 강하게 결합되어 있어 떼어낼 수 없는 정도
- 응집도 ⬆️
- 하나의 모듈이 스스로 자립할 수 있는 정도
# 단일 책임 원칙
“모든 객체는 책임을 하나만 져야 한다.”
- 객체나 모듈의 변경의 이유는 단 하나여야 한다
# 개방-패쇄 원칙
“확장에는 열려 있고, 변경에는 닫혀 있다.”
- 기능 추가시 기존 코드의 변경을 최소화해야 한다
# 리스코프 치환 원칙
“q(x)가 타입 T의 객체 x에 대해 증명할 수 있는 속성이라면 q(y)는 T의 하위 타입 S의 객체 y에 대해 증명할 수 있어야 한다.”
함수 계약 관계를 준수해야 함
- 구현체는 호출자의 의도(예상되는 동작)에 맞게 동작해야함
상속은 리스코프 치환 원칙을 위배하기 쉽다
- 부모 클래스의 메서드와 자식 클래스의 오버라이딩한 메서드가 서로 다른 동작이 가능
e.g. 이미지의 가로 크기를 늘리는 함수 (인자: Rectangle 타입)
- 이미지 객체는 Rectangle 타입(인터페이스) 이며 setWidth 메서드를 가지고 있음
- 이미지 객체의 setWidth 를 호출
- ⚠️ 문제 발생
- Rectangle 타입을 상속(구현)한 Square 타입이 매개변수로 넘어옴
- Square 타입의 setWidth 는 width와 height 를 모두 변경
- 가로 크기만 늘리려 했지만 세로 크기도 늘어남 (‼️ 예상치 못한 동작 발생)
# 인터페이스 분리 원칙
“클라이언트는 자신이 이용하지 않는 메서드에 의존하지 않아야 한다.”
- 인터페이스를 분리하여 불필요한 메서드들과의 의존 관계가 없어야 한다
# 의존 관계 역전 원칙
“상위 계층이 하위 계층에 의존하는 전통적인 의존 관계를 역전시킴으로써 상위 계층이 하위 계층의 구현으로부터 독립되게 할 수 있다.”
- 구체화된 객체는 추상화된 객체와 의존 관계를 가져야 한다
원칙
- 상위, 하위 모듈 모두 추상 모듈에 의존
- 추상 모듈은 구체화된 모듈에 의존해서는 안 된다. 구체화된 모듈은 추상 모듈에 의존해야 한다
이점
- 결합도가 낮아져 이식성이 증가
- 서로 독립성이 유지
# 테스트와 벤치마크
# 테스트 코드
|
|
- 파일명이
_text.go
로 끝나야 함 - testing 패키지를 가져와야 함
- 함수명은
Test
로 시작해야 함- 매개변수는
t *test.T
하나만 존재해야 함
- 매개변수는
stretchr/testify
- assert 객체
- 테스트 코드를 쉽게 만들 수 있는 다양한 메서드 포함
- Equal(), Greater(), Len(), NotNilf(), NotEqualf()
- 테스트 코드를 쉽게 만들 수 있는 다양한 메서드 포함
- mock 패키지
- 모듈의 행동을 가장하는 목업 객체 제공
- suite 패키지
- 테스트 준비 작업이나 종료 후 뒤처리 작업을 쉽게 할 수 있도록 도와줌
테스트 주도 개발
테스트 작성 -> 테스트 실패 -> 코드 작성 -> 테스트 성공 -> 개선(SOLID 원칙 입각)
- 위의 과정을 반복
# 벤치마크 코드
코드 성능을 측정
|
|
func BenchmarkXxxx(b *testing.B)
의 형태를 가져야 함
# Go로 만드는 웹서버
# 웹서버
- 핸들러 등록
- http.HandleFunc() -> DefaultServeMux 에 등록
- http.NewServeMux()
- ServeMux 객체 생성
- 생성한 ServeMux 객체의 HandleFunc() 를 호출하여 등록
- 웹서버 시작
- http.ListenAndServe(addr string, handler http.Handler)
- addr
- 포트번호
- handler
- http.Handler 의 구현체인
*http.ServeMux
사용 - nil 일 경우 내부적으로 DefaultServeMux 를 사용
- http.Handler 의 구현체인
- addr
- http.ListenAndServe(addr string, handler http.Handler)
구조
# 파일서버
|
|
- “/static” 안의 요청 URL.Path 에 해당하는 파일을 서빙
http.StripPrefix
로 요청 URL.Path 에서 “/static/” 제거
# 테스트 코드
|
|
# JSON 데이터 전송
Encoder, Decoder
- Encoder
io.Writer
를 가짐
- Decoder
io.Reader
를 가짐
- 한 번에 저장하는 대신 스트림 데이터를 인코딩, 디코딩
Marshal, Unmarshal
- Marshal
- any 타입의 값을 받아와 byte 슬라이스로 변환
- Unmarshal
- byte 슬라이스를 받아와 파싱한 결과를 any 타입(주소값)에 저장
- 모든 데이터를 byte 슬라이스에 저장하기 때문에 메모리 집약적
참조: https://blog.devgenius.io/to-unmarshal-or-to-decode-json-processing-in-go-explained-e92fab5b648f
# HTTPS
공개키 암호화 방식 사용
외부 공인 기관의 인증
피싱 사이트의 경우 해커가 공개키를 만들어 자신의 비밀키로 복호화할 수 있음
- 인증기관이 웹사이트를 인증 후 웹사이트의 공개키를 암호화한 공개키를 발급 (인증서에 포함)
키 생성 및 인증서 발급
|
|
https 서버 실행
|
|
# RESTful API 서버 만들기
REST (Representational State Transfer)
- URL과 메서드로 데이터와 동작을 표현하는 방식
특징
- URL과 메서드 조합으로 어떤 데이터에 대한 어떤 동작인지 정의
- 서버(백엔드)는 데이터 제공자로 데이터만 제공하고 클라이언트(프론트)에서 데이터를 처리하고 화면에 표시
- 무상태
- 서버는 클라이언트의 상태를 유지 하지 않음
- 캐시 처리
- 서버가 단순해져서 더 쉽게 캐시 정책 적용이 가능
코드
|
|