Go Lang 기초 13 - 인터페이스(interface)

만두아빠·2021년 7월 30일
1

Go Lang 기초

목록 보기
13/14


인터페이스를 알아보기 앞서 우선 객체지향 프로그래밍(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
profile
Velog는 잠시 쉬어갑니다! 아래의 링크로!

0개의 댓글