[Golang]コネクタとDuckTyping


インタフェース
宣言
type DuckInterface interface{
    Fly()
    Walk(distance int) int
}
interfaceがタイプです.すなわち、インタフェースタイプの変数を宣言することができる.
実施する必要はありません.インタフェースタイプに宣言する方法があれば、そのインタフェースになります.
逆に、あるオブジェクトがFly()Walk()の方法を実装する場合、DuckInterfaceと関係を確立することができる.
ルール#ルール#
  • メソッドにはメソッド名が必要です.
  • パラメータの戻りとは異なる場合でも、同じ名前のメソッドは使用できません.
  • インタフェースは、方法実装を含まない.
  • type Sample interface {
        String() string   // 이렇게 함수명, 입력, 출력만을 나타낸것을 시그니처라 한다.
        String(int) string // (x) 메서드명이 겹쳐서 안됨.
        _(x int) 		  // (x) 함수명이 없어서 안됨.
    }
    上記のルールに従ってインタフェースを作成します.
    type Stringer interface {
        String() string
    }
    
    type Student struct{
        name string
        age int
    }
    
    func (s Student) String() string{
        res := fmt.Sprintf("이름: %s 나이: %d", s.name, s.age)
        return res
    }
    
    func main() {
        student := Student{"철수", 12}
        var stringer Stringer
        
        stringer = student
        fmt.Println("%s\n", stringer.String())
    }
    nameageのフィールドを有するStudent構造体が作成され、StudentのタイプはString() stringの方法を有する.Stringerは文字列値を返すString()メソッドを有し、StudentタイプはString()メソッドを有し、したがってStringerインタフェースタイプとして宣言することができる.
    このときのstudentStringerを表しているといえる.
    私は何なのか知っていますが、どうして使いますか.
    以下に、fedex配送会社を用いてメールを送信するプログラムと、koreaPostを用いてメールを送信するプログラムを示す.Fedex宅配サービスを利用してメールを送信するプログラム
    package fedex
    
    import "fmt"
    
    type FedexSender struct {
        // ...
    }
    
    func (f *FedexSender) Send(parcel string) {
        fmt.Printf("Fedex sends %s parcel\n", parcel)
    }
    package main
    
    import "/fedex"
    
    func SendBook(name string, sender *fedex.FedexSender) {
        sender.Send(name)
    }
    
    func main() {
        sender := &fedex.FedexSender{}
        SendBook("어린 왕자", sender)
        SendBook("총균쇠", sender)
    }
    koreaPost宅配サービスを利用してメールを送信するプログラム
    package koreaPost
    
    import "fmt"
    
    type PostSender struct {
        // ...
    }
    
    func (k *PostSender) Send(parcel string) {
        fmt.Printf("우체국에서 택배 %s를 보냅니다\n", parcel)
    }
    package main
    
    import "/koreaPost"
    
    func SendBook(name string, sender *koreaPost.PostSender) {
        sender.Send(name)
    }
    
    func main(){
        sender := &koreaPost.PostSender{}
        SendBook("어린왕자", sender)
        SendBook("총균쇠", sender)
    }
    
    いずれにしても、同じ機能を実行するコードなので、似たような構造を持つコードがほとんど見られます.この場合、最初にfedex倍のメールを送信するプログラムを作成しましたが、何らかの理由でkoreaPost倍のメールを使用する必要があります.それなら修正が必要なところがあります.
  • 2sender変数のタイプは、fedex.PostSender->koreaPost.PostSenderに変更する必要があります.
  • 2Sendbook()メソッドのsenderパラメータ値も変更します.
  • このようにmain.goから現在までfedex配送会社を使用して우체국に行くと、main.goでコード修正が発生します.この場合,インタフェースを用いてコード修正量を減らすことができ,fedex.PostSenderタイプとkoreaPost.PostSenderタイプにはSend()の方法がある.Send()の方法を制定したinterfaceのタイプであれば、どの宅配会社が宅配便を送っても、コードを修正する必要はありません.したがって、インタフェースを使用してコードの変更を最小限に抑えることができます.
    package main
    
    import "/koreaPost"
    
    // sender interface 선언
    type Sender interface{
        Sender(parcel string)
    }
    
    func SendBook(name string, sender Sender) {
        sender.Send(name)
    }
    
    func main(){
        // sender := &fedex.PostSender{}
        sender := &koreaPost.PostSender{}
        
        var senderInterface Sender
        senderInterface = sender
        SendBook("어린왕자", senderInterface)
        SendBook("총균쇠", senderInterface)
        
    }
    このようにインタフェースを用いてコードを記述し,配送会社を交換する必要がある場合,sender変数のタイプを変更するだけで修正が完了する.それだけでなく、宅配便を送る場合、fedexに送るにしても郵便局に送るにしても、内部送信の過程を詳しく知らなくても、抽象化が依存性を解消できるため、送信することができます.
    タイプを打つ
    ???: もし鳥がアヒルのように歩いていて、アヒルのように飛んでいて、アヒルのように鳴いていたら、私はアヒルと呼んでいます.
    あなたがどんなタイプであろうと、Send()の方法があれば、私はあなたをSenderと呼びます.つまり.
    オブジェクトをインタフェースに代入すると(studentInterface = student)、オブジェクトにインタフェースが必要なメソッドがあるかどうかを確認します.そうしないと、コンパイルエラーが発生します.
    この方法は,タイプを宣言する際にインタフェースを実装するか否かを指定するのではなく,インタフェースを使用する際に決定するので,ユーザ中心でプログラミングすることができる.すなわち、オブジェクトを作成して使用すると、インタフェースが必要だと思ったら、インタフェースを定義して使用できます.
    マッピング以外の方法でオブジェクトを作成する場合は、オブジェクトを作成するたびにインタフェースを使用するかどうかを予測し、インタフェースが必要かどうかを変更するときにコードを変更する方法が大好きです.これは、開発者にとって非常に満足しています.これは友好的な方法だと思います.
    この文章はTuckerのGo言語プログラミングコースの内容に基づいて整理されています.
    YouTubeリンク:TuckerのGo言語プログラミング