IT/Develop
-
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (3) 기본 템플릿 작성2021.08.20
-
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (2) 튜토리얼 개요2021.08.20
-
Go Lang 기초 14 - 고 루틴(Go Routine)2021.08.02
-
Go Lang 기초 13 - 인터페이스(interface)2021.07.30
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (3) 기본 템플릿 작성
해당 튜토리얼은 'Building Go Web Applications and Microservices Using Gin'의 내용을 번역하며 개인적으로 정리한 것입니다.
이번 시간에는 Gin Web Framework를 기초로, 기본적인 구조를 직접 만들어보고자 합니다.
1. 의존성 설치
튜토리얼에서 사용할 어플리케이션에서는 외부 의존성 프로그램인 Gin 프레임워크만을 사용합니다. 다음 명령어를 입력하여 최신 버전을 설치해주세요.
$ go get -u github.com/gin-gonic/gin
2. 재활용 가능한 템플릿 만들기
우리가 제작할 어플리케이션은 템플릿을 사용하여 웹 페이지를 표시합니다. 해당 페이지에는 Header, Menu, Sidebar 및 footer와 같은 여러 부분이 필요할 것이며 이 부분들은 모든 페이지에서 공통적으로 사용됩니다. Go Lang을 사용해서 다른 템플릿에서 가져올 수 있는 재사용 가능한 템플릿 스니펫을 만들 수 있습니다.
Header와 Footer는 모든 템플릿에서 공통적으로 재사용되는 부분입니다. 따라서 제작 순서는 Header 템플릿에서 사용할 자체 템플릿 파일에 메뉴를 생성하고, Header와 Footer를 가져올 인덱스 페이지용 템플릿을 만드는 식이 될 것입니다. 지금 생성할 모든 템플릿 파일들은 templates라는 이름의 별도의 디렉토리안에 배치하도록 합니다. 먼저 튜토리얼을 시작하고자하는 폴더 안에 templates 폴더를 생성하고 menu.html 파일을 작성하는 것부터 시작해보도록 하겠습니다.
▶ templates/menu.html
<!--menu.html 모든 페이지에서 공통으로 사용-->
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">
홈으로
</a>
</div>
</div>
</nav>
우선 현재 메뉴에는 홈 화면으로 돌아갈 수 있는 링크만 포함이 되어 있습니다. 우리는 어플리케이션에 기능을 추가할 때, 여기에 하나씩 추가하게 될 것입니다.
▶ templates/header.html
<!-- header.html -->
<!doctype html>
<html>
<head>
<!-- 타이틀 페이지를 세팅하기 위해 타이틀을 변수로 사용합니다 -->
<title>{{ .title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<!-- 부트스트랩을 사용해서 멋진 어플리케이션을 만들어봅시다 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script async src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</head>
<body class="container">
<!-- 이 위치에 menu.html 템플릿 포함시키기 -->
{{ template "menu.html" . }}
▶ templates/footer.html
<!--footer.html-->
</body>
</html>
튜토리얼을 제작하기 위해 우리는 오픈소스 부트스트랩의 프레임워크를 사용합니다. 파일의 대부분은 HTML형식을 가지고 있습니다. 다만 우리가 여기서 주목해야할 부분이 두 줄 있습니다.
<title>{{ .title }}</title>
위의 코드는 어플리케이션 안에서 설정해야하는 .title 변수를 사용하여 페이지 제목을 동적으로 설정하는데 사용됩니다.
{{ template "menu.html" . }}
위의 코드는 menu.html파일에서 메뉴 템플릿을 가져오는데 사용됩니다. Go Lang은 이러한 방식을 사용하여 하나의 템플릿을 다른 템플릿으로 가져올 수 있습니다.
Footer 템플릿에 정적 HTML이 포함되어 있습니다. 인덱스 페이지의 템플릿은 Header와 Footer를 사용하게 하고, 간단하게 안녕 Gin? 이라는 메시지를 출력할 수 있도록 해봅시다.
▶ templates/index.html
<!-- index.html -->
<!-- header.html 템플릿을 이 위치에 포함시킵니다 -->
{{ template "header.html" .}}
<h1>안녕 Gin?</h1>
<!-- footer.html 템플릿을 이 위치에 포함시킵니다 -->
{{ template "footer.html" .}}
인덱스 템플릿과 마찬가지로 다른 페이지의 템플릿도 비슷한 방식으로 Header와 Footer 템플릿을 재사용할 것입니다.
여기까지 따라오셨다면 어플리케이션의 디렉토리 구조는 다음과 같이 구성되어 있을 것입니다.
다음 시간에는 본격적으로 어플리케이션 구동을 위한 파일들을 생성해볼 것입니다. 원래 계획대로라면 Gin 체험하기 (3)에서 기본 템플릿 작성과 라우터 생성하고 안녕 Gin 부분을 로컬호스트를 통해 구동하는 부분까지 진행해보려 했습니다만 다 합치다보니 글이 너무 길어지기에 부득이하게 분리하여 업로드할 계획입니다. 포스팅 내용이 과하게 짧은 것은 저도 좋아하지 않지만, 필요한 부분만 찾아서 보시기를 원하시는 분들이 계실 수 있다는 생각을 하고 있기에 이런 결정을 하게 되었습니다.
언제나 많은 피드백을 부탁드리고 감사히 받고 있습니다. 감사합니다!
'IT > Develop' 카테고리의 다른 글
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (5) 라우터 초기화, 기사 목록 모델 테스트 (0) | 2021.08.21 |
---|---|
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (4) 템플릿 연결하기 (0) | 2021.08.20 |
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (2) 튜토리얼 개요 (0) | 2021.08.20 |
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (1) Web Framework 기초 (0) | 2021.08.16 |
Go Lang 기초 14 - 고 루틴(Go Routine) (0) | 2021.08.02 |
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (2) 튜토리얼 개요
해당 튜토리얼은 'Building Go Web Applications and Microservices Using Gin'의 내용을 번역하며 개인적으로 정리한 것입니다.
이번 시간부터 우리는 Go Lang의 Gin Web Framework를 사용해서 기사(Article) 목록과 기사의 세부 정보를 표시하는 간단한 웹 어플리케이션을 구축해볼 것입니다. 이번 튜토리얼을 통해 우리는 Gin Web Framework를 사용해서 웹 어플리케이션을 구축하는 전반적인 방법을 공부해볼 수 있을 것입니다.
0. 시작 전에
튜토리얼 진행을 위해서 우선 Go, curl, git 이 설치되어 있어야 합니다.
1. 왜 Gin으로 제작하나요?
Gin은 웹 어플리케이션, 마이크로 서비스를 구축하는데 사용할 수 있는 고성능 마이크로 프레임워크입니다. Go Lang의 내장 라이브러리인 net/http는 HTTP 서버를 쉽고 간편하게 만들 수 있는 훌륭한 기능이지만, 유연성이 떨어지고 구현을 위해 일부 상용 코드를 필요로 합니다. 또한 Go Lang에는 '패턴'을 기반으로 하는 경로를 처리하는 내장 지원 기능이 없습니다. 추가 코드 작성을 통해 기능을 구현할 수 있으나 코드를 모든 곳에서 반복사용하거나, 재사용을 위한 라이브러리를 제작해야할 가능성이 높습니다.
Gin에서는 이러한 상용 코드를 줄이고 웹 어플리케이션 작성을 간단하게 만들어 줄 수 있는 라우팅, 미들웨어 지원, 렌더링과 같은 기능들이 포함되어 있습니다.
2. 어플리케이션 설계
Gin에서 Request가 어떻게 처리되는지 간단히 살펴보고 가도록 합시다. 일반적인 웹 어플리케이션, API 서버, 마이크로서비스에 대한 제어 흐름은 다음과 같습니다.
요청(Request) ➡ 라우터 분석(Route Parser) ➡ ([선택사항] 미들웨어) ➡ 라우터 핸들러(Route handler) ➡ ([선택사항] 미들웨어) ➡ 응답(Response)
3. 어플리케이션 기능
튜토리얼을 통해 우리가 직접 만들어볼 어플리케이션은 간단한 기사(Article) 관리 웹 페이지입니다. 이 어플리케이션은 다음과 같은 기능을 수행하도록 작성할 것입니다.
- (로그인하지 않은) 사용자가 사용자 이름과 패스워드를 등록할 수 있도록 합니다
- (로그인하지 않은) 사용자가 사용자 이름과 패스워드로 로그인하도록 합니다
- (로그인한) 사용자가 로그아웃할 수 있도록 합니다
- (로그인한) 사용자가 새 기사(Article)를 작성할 수 있도록 합니다
- (모든 유저가) 메인 페이지의 모든 기사 목록을 표시합니다
- (모든 유저가) 자체 페이지에 단일 기사를 표시합니다
해당 기능들 외에도 기사 목록과 하나의 기사는 HTML, JSON, XML 형식으로 접근할 수 있어야합니다.
이 과정들을 통해 우리는 Gin을 사용하여 기존 웹 어플리케이션, API 서버, 마이크로서비스를 설계하는 방법을 그려낼 수 있습니다. 우리는 Gin이 제공하는 다음의 기능들을 사용할 것입니다.
- 라우팅(Routing) : 다양한 URL의 처리
- 사용자정의 렌더링(Custom rendering) : 응답(Response) 형식을 처리
- 미들웨어(Middleware) : 인증(authentication)을 구현
또한 모든 기능이 의도한대로 작동하는지 테스트를 통한 검증도 작성할 것입니다.
4. 라우팅(Routing)
라우팅(Routing)은 모든 최신 프레임워크들이 제공하는 핵심 기능 중 하나입니다. 모든 웹 페이지, API 엔드포인트는 URL로 액세스됩니다. 프레임워크는 라우트를 사용하여 이러한 URL에 대한 요청을 처리합니다.
예를 들어, URL이 http://www.example.com/some/random/route 이면 경로는 /some/random/route 가 되는 것입니다.
Gin은 구성과 활용이 용이하고 빠른 간편 라우터를 제공합니다. 지정된 URL을 처리하는 것 외에도 Gin 라우터는 패턴, 그룹화된 URL도 처리할 수 있습니다.
이번 튜토리얼에서 우리는,
- / (HTTP GET 요청) 경로에 인덱스 페이지를 제공합니다 .
- /u 라우터 하위 페이지에 사용자 관련 경로를 그룹화하고,
- /u/login(HTTP GET 요청) 에서 로그인 페이지를 제공합니다
- /u/login(HTTP POST 요청) 에서 로그인 자격 증명을 처리합니다
- /u/logout(HTTP GET 요청) 에서 로그아웃합니다
- /u/register(HTTP GET 요청) 에서 등록 페이지를 제공합니다
- /u/register(HTTP POST 요청) 에서 등록 정보를 처리합니다
- /article 루트 하위 페이지에 기사글을 그룹화하고,
- /article/create(HTTP GET 요청) 에서 기사 생성 페이지를 제공합니다
- /article/create(HTTP POST 요청) 에서 제출된 기사를 처리하고,
- /article/view/:article_id(HTTP GET 요청) 에서 기사 페이지를 제공합니다 특히, :article_id 이 부분은 주의해주세요. : 으로 시작하는 부분이 동적 라우터(Dynamic Route)임을 나타냅니다. 이는 :article_id의 모든 값을 포함할 수 있으며 Gin은 이 값을 라우트 핸들러(Route handler - 경로처리) 에서 사용할 수 있도록 합니다.
5. 렌더링(Rendering)
웹 어플리케이션은 HTML, TEXT, JSON, XML, 기타 형식과 같이 다양한 형식으로 응답을 렌더링할 수 있습니다. API 엔드포인트와 마이크로서비스는 일반적으로 JSON 형식뿐만 아니라 원하는 다른 형식의 데이터로도 응답이 가능합니다.
다음 섹션을 통해서 우리는 기능을 복제하지 않고도 다양한 유형의 응답을 렌더링하는 방법을 살펴볼 것입니다. 우리는 주로 HTML 템플릿으로 요청에 응답합니다. 그러나 JSON, XML 데이터로 응답할 수 있는 두 엔드포인트도 정의할 것입니다.
6. 미들웨어(Middleware)
Go Lang 웹 어플리케이션의 관점에서 보자면 미들웨어는 HTTP 요청을 처리하는 동안 모든 단계에서 실행할 수 있는 코드의 조각입니다. 일반적으로 여러 경로에 적용하려는 공통 기능을 캡슐화(encapsulate)하는 데 사용됩니다. HTTP 요청이 처리되기 전, 후에 미들웨어를 사용할 수 있습니다. 미들웨어의 일반적인 용도에는 권한 부여, 유효성 검사 등이 있습니다.
요청이 처리되기 전에 미들웨어가 사용되는 경우, 요청에 대한 변경 사항은 메인 라우터 핸들러에서 사용할 수 있습니다. 이는 특정 요청에 대해 일부 유효성 검사를 구현하려는 경우에 편리합니다. 반면에 라우트 핸들러 이후에 미들웨어를 사용하면 라우트 핸들러로부터 응답을 받게 됩니다. 이 경우 라우터 핸들러의 응답을 수정하는 데 사용할 수 있습니다.
Gin을 사용하면 여러 경로를 처리하는 동안, 공유해야 하는 몇 가지 공통 기능을 구현하는 미들웨어를 작성할 수 있습니다. 이것은 코드베이스를 작게 유지하고 관심사를 분리하며 코드 유지 관리성을 향상시킵니다.
코드베이스(Code base) : 특정 시스템, 애플리케이션, 컴포넌트 등을 빌드할 때 사용되는 소스코드의 전체집합, 그것을 담은 저장소
우리는 일부 페이지와 작업이 다음과 같은지 명확히 해야합니다. 예를 들어, 기사 작성, 로그아웃은 로그인한 사용자만 가능하도록 하고, 일부 페이지 및 작업(회원가입, 로그인)은 로그인하지 않은 사용자만 가능하도록 하는 것 등을 말합니다.
이 논리를 모든 경로에 적용하면 상당히 지루하고 반복적이며 오류가 발생하기 쉽습니다. 운 좋게도 이러한 각 작업에 대한 미들웨어를 만들고 특정 경로에서 재사용할 수 있습니다.
우리는 튜토리얼에서 모든 경로에 적용시킬 미들웨어를 만들 것입니다. 이 미들웨어(setUserStatus)는 인증된 사용자의 요청인지 여부를 검사합니다. 그런 다음 템플릿에서 이 플래그를 기반으로 하는 일부 메뉴 링크의 가시성을 수정하는 데 사용할 수 있는 플래그를 설정합니다.
다음 시간부터는 본격적으로 Gin Web Framework를 설치하고 웹 페이지를 구성할 HTML 파일들과 main.go 에 들어갈 소스코드를 직접 작성해보도록 하겠습니다. 위의 내용은 전반적인 기본 지식으로, 이해하신 내용들을 기반으로 다음 단계의 작업을 진행하시면 더욱 튜토리얼을 효율적으로 공부하실 수 있을 것입니다.
'IT > Develop' 카테고리의 다른 글
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (4) 템플릿 연결하기 (0) | 2021.08.20 |
---|---|
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (3) 기본 템플릿 작성 (0) | 2021.08.20 |
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (1) Web Framework 기초 (0) | 2021.08.16 |
Go Lang 기초 14 - 고 루틴(Go Routine) (0) | 2021.08.02 |
Go Lang 기초 13 - 인터페이스(interface) (0) | 2021.07.30 |
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (1) Web Framework 기초
많은 프로그래밍 언어들은 저마다의 멋진 프레임워크와 라이브러리를 가지고 있습니다.
일반적으로 프로그래밍 언어를 사용할 때 말하는 라이브러리(Library)란 쉽게 가져와서 사용할 수 있는 도구들을 모아놓은 공구함같은 것이라고 생각하시면 됩니다. 프로그래밍을 할 때 필요할만한 도구들을 가져와서 개발환경에 맞게 사용할 수 있도록 제공하는 도구죠.
이에 반해 프레임워크(Framework)는 흔히 말하는 뼈대, 기본골격을 의미합니다. 이 안에는 여러 인터페이스와 컴포넌트들이 포함이 되어있습니다. 일정한 뼈대가 잡혀있고 그 안에서 개발자가 자신의 목표에 맞는 도구들을 사용해서 결과물을 만들어낼 수 있도록 돕는 역할을 하는 것이죠.
국내에서 정말 많이 사용되는 유명 프레임워크로는 JAVA의 Spring이 있습니다. 채용 홈페이지에서도 대부분의 JAVA 개발자 채용의 경우 Spring Framework에 대한 경험을 필수 혹은 우대한다는 내용의 Job description을 심심치 않게 확인할 수 있습니다.
비단 JAVA만 그런 것이 아닙니다. Ruby on Rails, Python의 django 또한 해당 언어를 사용하는 개발자라면 누구나 사용해봤거나 공부해보고자할 정도로 널리 알려진 프레임워크입니다. 해당 언어를 사용하지 않는 개발자들도 딱 들으면 알 정도로 유명합니다.
Go Lang에서는 이런 JAVA의 spring, Python의 django 같은, 언어를 대표할만한 프레임워크가 어떤 것이 있을까요?
GitHub에 한 repo는 GitHub의 STAR를 받은 수를 기준으로 Go Lang의 Web Framework 순위를 집계하고 있습니다.
https://github.com/mingrammer/go-web-framework-stars
작년까지는 가장 많은 star를 받은 Gin과 두번째로 많이 받은 Beego 간의 star 차이가 크지 않았는데 2021년 8월 현재를 기준으로 Gin 5만 vs Beego 2.6만 정도로 거의 2배에 가까운 차이를 벌렸습니다. Gin이 압도적으로 치고 올라가는 모습입니다. 개발에 있어 가장 많은 사용자가 있고, 가장 이슈와 포크가 활성화된 오픈소스는 분명히 큰 장점을 가집니다.
Gin은 사용이 간편하면서도 빠른 속도가 장점인 프레임워크입니다. Go Lang의 프레임워크 체험해보기에 아주 좋을 것입니다.
1. Gin 설치하기
Gin의 패키지를 설치하려면 Go version이 1.13이상이어야 합니다.
Mac은 터미널, 윈도우에서는 CMD를 통해 다음 명령어를 입력하여 패키지를 설치합니다.
$ go version : Go 버전 확인
$ go get -u github.com/gin-gonic/gin : Gin 패키지 설치
패키지 설치가 끝나면 작성할 코드에 Gin을 임포트합니다
import github.com/gin-gonic/gin
Gin 가이드에 따르면 필요에 따라 net/http 임포트를 하도록 권장하고 있는데, IDE 환경에서 작성 시 별도의 임포트를 하지 않아도 자동으로 임포트되므로 놓치더라도 큰 문제가 발생하지 않을 것입니다.
2. 간단 예제 작성으로 동작시켜보기
다음의 예제를 작성하여 Gin 패키지가 제대로 동작하는지 직접 확인해보도록 합시다.
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
위의 예제를 직접 작성해서 실행하시면 GET/ping 서버가 동작하고, 메시지가 잘 출력되고 있음을 확인할 수 있습니다.
Gin으로 기본적인 Router를 만드는 방법은 다음과 같습니다.
r := gin.Default()
예제에는 r을 사용했지만 Gin의 다른 많은 예제에서는 router 로 정의하고 있습니다.
서버 포트 변경을 위해서 r.Run에서 원하는 포트번호값을 입력해줄 수 있습니다.
r.Run(":포트번호")
3. GET, POST, PUT, PATCH, DELETE, OPTIONS 사용하기
Gin을 통해 REST API 설계를 작성해볼 수 있습니다
func main() {
router := gin.Default()
router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)
router.Run()
}
다음 포스팅에서는 Gin 프레임워크를 활용하여 직접 간단한 웹 서버를 만들어보는 예제를 통해 조금 더 상세한 내용을 알아보도록 하겠습니다.
'IT > Develop' 카테고리의 다른 글
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (3) 기본 템플릿 작성 (0) | 2021.08.20 |
---|---|
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (2) 튜토리얼 개요 (0) | 2021.08.20 |
Go Lang 기초 14 - 고 루틴(Go Routine) (0) | 2021.08.02 |
Go Lang 기초 13 - 인터페이스(interface) (0) | 2021.07.30 |
Go Lang 기초 12 - 메소드(Method) (0) | 2021.07.28 |
Go Lang 기초 14 - 고 루틴(Go Routine)
Go Lang에서는 동시에 실행되는 작업을 Go Routine이라고 부릅니다.
다른 프로그래밍언어에서 쓰레드(Thread)라고 부르는 것과 유사한 개념이지만, Go Routine은 OS 쓰레드와 1 대 1로 대응되지 않고 훨씬 적은 OS 쓰레드를 사용합니다. 따라서 한 번에 더 많은 Go Routine을 실행할 수 있습니다.
Go Routine은 사용하기도 매우 간편합니다.
go 함수명()
동시성(Concurrent)은 싱글 코어의 경우에서 스레드를 여러 개 만들어서 마치 동시에 실행되는 것'처럼' 보이도록 하는 것입니다.
병렬성(parallel)은 멀티 코어에서 실제로 나눠서 작업을 동시에 처리하는 것을 말합니다.
동시성을 구현하기 위해 사용되는 개념이 멀티프로세싱과 멀티쓰레딩입니다.
프로세스는 운영체제로부터 자원을 할당받는 작업의 단위이며, 쓰레드는 프로세스가 할당받는 자원을 이용하는 실행의 단위를 말합니다.
동시성을 지원하도록 작성된 프로그램은 여러 작업을 동시에 실행하는 병렬성도 지원할 수 있습니다. 이를 통해 프로그램의 속도를 크게 향상시킬 수 있습니다.
예제. 고 루틴 사용해보기
package main
import (
"fmt"
"time"
)
func printa() {
for i := 0; i < 10; i++ {
fmt.Print("A")
}
}
func printb() {
for i := 0; i < 10; i++ {
fmt.Print("B")
}
}
func printc() {
for i := 0; i < 10; i++ {
fmt.Print("C")
}
}
func main() {
go printa()
go printb()
go printc()
time.Sleep(time.Second)
fmt.Println("\nGo Routine End")
}
출력결과물
BCCCCCCCCCCBABBBBBBBBAAAAAAAAA
Go Routine End
출력결과물이 함수 위치순서대로가 아니라 뒤섞여있는 이유는, Go Routine을 통해 세가지 함수가 동시에 실행되기 때문입니다. 따라서 출력결과물은 실행시킬 때마다 매번 조금씩 다르게 나타나실 겁니다.
CPU를 최대한 활용하려면 runtime.NumCPU()를 사용합니다.
예제. 고 루틴 runtime 활용하기
package main
import (
"fmt"
"runtime"
"time"
)
func printa() {
for i := 0; i < 10; i++ {
fmt.Print("A")
}
}
func printb() {
for i := 0; i < 10; i++ {
fmt.Print("B")
}
}
func printc() {
for i := 0; i < 10; i++ {
fmt.Print("C")
}
}
func main() {
fmt.Println(runtime.NumCPU())
runtime.GOMAXPROCS(runtime.NumCPU())
go printa()
go printb()
go printc()
time.Sleep(time.Second)
fmt.Println("\nGo Routine End")
}
출력결과물
12
AAAAAAAAAABBBBBBBBBBCCCCCCCCCC
Go Routine End
go 1.5 버전 이상부터는 runtime.GOMAXPROCS()를 따로 설정하지 않으면 모든 CPU를 활용하는 것이 기본입니다.
runtime.GOMAXPROCS(4) 등을 통해 활용 CPU의 수를 조절합니다.
'IT > Develop' 카테고리의 다른 글
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (2) 튜토리얼 개요 (0) | 2021.08.20 |
---|---|
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (1) Web Framework 기초 (0) | 2021.08.16 |
Go Lang 기초 13 - 인터페이스(interface) (0) | 2021.07.30 |
Go Lang 기초 12 - 메소드(Method) (0) | 2021.07.28 |
Go Lang 기초 11 - 구조체(Struct) (0) | 2021.07.28 |
Go Lang 기초 13 - 인터페이스(interface)
인터페이스를 알아보기 앞서 우선 객체지향 프로그래밍(OOP)에 대해 먼저 알아보도록 하겠습니다. 도움이 될 것입니다.
OOP(Object-Oriented Programming)는 프로그램 설계방법론의 하나입니다. 프로그램을 수많은 객체(Object)들로 나누고 이 객체 간의 상호작용을 통해 서술해나가는 방식을 말합니다. 대중적으로 많이 쓰이는 Java, Python, 그리고 Go Lang이 여기에 해당됩니다.
OOP는 유지보수가 쉽고, 코드가 간결해지는 등 많은 장점을 가진 방식이지만,
처리 시간이 오래 걸리고 무엇보다 프로그램 설계 단계부터 꼼꼼하게 생각하고 작성해야 문제가 생기지 않는다는 단점 또한 존재합니다. 알아야할 내용도 많고, 익숙해지는데 많은 시간을 필요로하기도 합니다.
시간이 지날수록 생기는 여러가지 문제점들을 극복해보고자 Beyond OOP라는 단어가 떠오르기 시작했습니다. 기존의 OOP는 Object 중심이므로 클래스의 갯수가 많고, 이를 처음 작성한 사람이 이직하거나 그만두게 되어 다른 개발자가 온다면 구조를 처음 분석하고 파악하는데에도 많은 시간이 필요로 합니다.
실리콘 벨리와 같은 곳에서는 Make Fast, Break things 라는 말이 유행이었다고 합니다. OOP는 잘 짜여진 구조를 설계하는 것이 매우 중요한데, 시간에 쫓기거나 실력의 부족으로 코드가 꼬이게 되면 기술 부채가 쌓이게 됩니다. 그리고 기술 부채가 쌓이게 되면 언젠가는 프로그램이 무너질 수 밖에 없을 것입니다. OOP를 넘어서야 이 Make Fast, Break things를 실현해낼 수 있습니다.
우리는 Go Lang을 통해 Beyond OOP를 실현해내는데 한 발 더 나아가볼 것입니다.
Go Lang의 인터페이스(interface)는 특정 값이 가지고 있기를 기대하는 메소드의 집합, 동작을 수행할 수 있는 타입이 지녀야하는 동작들의 집합입니다.
이 Go Lang에서는 인터페이스를 통한 객체의 상태와 기능을 디커플링(Decupling)시켜 object에 종속되어있던 기능을 종속해제합니다. 디커플링을 통해 기존에 OOP의 단점인, 클래스마다 차지하고 있는 기능들이 메모리를 많이 차지하던 문제에서 효율성을 추구할 수 있게 합니다.
인터페이스의 형태
type 인터페이스명 interface {
메소드명()
메소드명(매개변수타입)
메소드명() 반환값타입
}
인터페이스 정의에 나열된 모든 메소드를 가진 타입은 해당 인터페이스를 만족한다고 합니다. 인터페이스를 만족하는 타입은 해당 인터페이스가 필요한 모든 곳에서 사용할 수 있습니다.
인터페이스를 만족하려면 인터페이스에 정의된 메소드명, 매개변수 타입, 반환값 타입이 모두 일치해야합니다. 인터페이스 정의에 나열된 메소드는 반드시 모두 구현해야하며 하나라도 구현하지 않으면 인터페이스를 만족할 수 없습니다
예제. 인터페이스 만들기
package main
import "fmt"
type SamHero interface { // 삼국지 영웅의 행동 세 가지를 인터페이스로 만들어보겠습니다
Battle() // '전투' 메소드 작성
Diplomacy // 인터페이스도 하나의 타입이므로 인터페이스에 포함시킬 수 있습니다
}
type Diplomacy interface { // '외교' 인터페이스 안에 동맹과 배신을 만들어줍니다
Allay() // '동맹' 메소드 생성
Betray() // '배신' 메소드 생성
}
type Hero struct { // 영웅 구조체를 만듭니다
}
// '전투' 메소드
func (p Hero) Battle() {
fmt.Println("전투를 개시합니다")
}
// '동맹' 메소드
func (p Hero) Allay() {
fmt.Println("동맹을 맺습니다")
}
// '배신' 메소드
func (p Hero) Betray() {
fmt.Println("동맹을 배신합니다")
}
func main() {
var h SamHero // 변수 b 선언을 통해 인터페이스를 사용해줍니다
h = Hero{} // 구조체와 연결합니다
h.Battle() // '전투' 메소드 호출
h.Allay() // '동맹' 메소드 호출
h.Betray() // '배신' 메소드 호출
}
출력결과물
전투를 개시합니다
동맹을 맺습니다
동맹을 배신합니다
인터페이스는 비어있는 상태로도 사용이 가능합니다. 말 그대로 빈 인터페이스(Empty interface)입니다.
var a interface {}
빈 인터페이스는 말 그대로 비어있는 인터페이스이기 때문에 모든 타입의 값을 가질 수 있습니다. 일반적으로는 알 수 없는 값을 처리할 때 사용합니다.
예제. 빈 인터페이스 만들어보기
package main
import "fmt"
func main() {
var a interface{}
fmt.Println(a)
a = 3
fmt.Println(a)
a = "Mandoo"
fmt.Println(a)
}
출력결과물
<nil>
3
Mandoo
'IT > Develop' 카테고리의 다른 글
Go Lang 웹 프레임워크 기초 - Gin 체험하기 (1) Web Framework 기초 (0) | 2021.08.16 |
---|---|
Go Lang 기초 14 - 고 루틴(Go Routine) (0) | 2021.08.02 |
Go Lang 기초 12 - 메소드(Method) (0) | 2021.07.28 |
Go Lang 기초 11 - 구조체(Struct) (0) | 2021.07.28 |
Go Lang 기초 10 - 맵(Map) (0) | 2021.07.28 |