변환
인터페이스 변환
type Mover interface {
Move()
}
type Locker interface {
Lock()
Unlock()
}
type MoveLocker interface {
Mover
Locker
}
type bike struct {}
func (bike) Move() {
fmt.Println("Moving the bike")
}
func (bike) Lock() {
fmt.Println("Locking the bike")
}
func (bike) Unlock() {
fmt.Println("Unlocking the bike")
}
func main() {
var ml MoveLocker
var m Mover
ml = bike{}
m = ml //ok
ml = m //x
}
- 각각의 매소드에 인터페이스를 설정한다.
- bike에 필요한 매소드를 선언한다.
- ml(movelocker interface)에 bike를 대입한다.(각각의 매소드가 정의되어있기때문에 대입가능)
- 그 ml(movelocker)을 m(mover)에 할당한다. -> 당연히 매소드가 포함되어있기때문에 변환가능하다.
- 하지만 역으로 다시하려고하면 m(mover)에는 locker에 대해서 정의내려지고 있지않기때문에 lock method missing으로 에러가 발생한다.
- 실제로 대입되어있는 값이 매소드를 가지고 있을지라도 타입간에 호환이 맞지않기때문에 불가능하다.
타입 단언(type asserion)
- 이런 상황에서는 런타임때 타입단언을 사용하여 명시적으로 변환 시킬 수 있다.
- m.(bike)라는 식의 interface.(type)을 통해서 인터페이스의 타입을 명시적 표시할 수 있다.
- 이렇게 되면, ml = m.(bike)와 같이 선언할 수 있다.
- 타입단언을 사용하면 주의해야되는게, 인터페이스로 추상화하고 디커플링시켰는데, 타입단언을 하게되면 이전상태로 돌아가게 되기때문이다.
인터페이스 오염(interface pollution)
- 구체적인 타입이 아닌 인터페이스로 선언하는건 왜그런가?
- 인터페이스를 사용하기위해서 인터페이스를 사용한다
- 아니다. 인터페이스 사용에는 비용이 들기때문에, 사용에 득보다 실이 많으면 인터페이스를 사용하면 안된다.
- 인터페이스를 사용하기위해서 인터페이스를 사용한다
- 코드 테스트를 위해서 인터페이스를 사용한다
- 아니다. 개발자를 우선하여서 개발해야한다.
- 코드 테스트를 위해서 인터페이스를 사용한다
- 오염된 코드의 예시이다.
type Server interface {
Start() error
Stop() error
Wait() error
}
type server struct {
host string
}
func NewServer(host string) Server {
return &server{host} // 외부에서 사용시 export되지않는 타입을 리턴함- 좋지않은 구조
}
func (s *server) Start() error {
return nil
}
func (s *server) Stop() error {
return nil
}
func (s *server) Wait() error {
return nil
}
func main() {
srv := NewServer("localhost")
srv.Start()
srv.Stop()
srv.Wait()
}
- 이런경우, srv는 추상화될 필요가 없던 부분이다.
- interface가 없더라도 달라질게 없는 코드이다.
- export되지않는 변수를 사용
- 변화에 잘 대응되도록 디커플링 되어있지않음.
인터페이스 오염 제거
server struct -> Server struct, 그리고 newServer 리턴값을 Server struct
그러면 Server가 외부에서 참조가 가능해지고, Server가 매소드를 호출하는 방식으로 변경되게된다.
인터페이스 사용가이드
- 유저가 api(?)의 실제 구현 디테일을 작성할때
- api가 유지보수가 필요한 다양한 구현을 가지고 있을때
- api가 변할수 있을때 디커플링을 사용한다.
이럴때 사용을 다시한번 고려해본다
- 테스트만을 위해서
- 변화로 부터 쉽게 대응불가
- 인터페이스가 코드를 더 좋게 만들어 주지 않는다.
'프로그래밍 > golang' 카테고리의 다른 글
ultimate in go-(10) data race (0) | 2023.01.29 |
---|---|
ultimate in go-(9) 동시성(고루틴) (0) | 2023.01.26 |
ultimate in go(7)- decoupling (0) | 2023.01.24 |
ultimate in go (6)- grouping (0) | 2023.01.24 |
ultimate in go (5)- data structure(embedding) (0) | 2023.01.24 |