goでマルチステートを実現する方法

1959 ワード

接触goはもうすぐ半年になりますが、やはりその時に検索する状態に属して、系統的な研究がありません
goは強いタイプの言語で、phpからgoに切り替えるたびに少し慣れないが、優雅さを追求するには妥協すべきではない.
goはimplements、extendsキーワードがないので、OOPプログラミングに慣れているので、最初はちょっと違和感があるかもしれません.しかしgoは優雅な言語として、私たちにもう一つの解決策を提供してくれました.それはアヒルのタイプです.アヒルのように見えますが、それはアヒルです.
では、アヒルのタイプとは何か、どのように実現するのでしょうか.
次に、この実装スキームを簡単な例で説明します.
まずスーパークラスが必要です.
type Animal interface {
    Sleep()
    Age() int
    Type() string
}

必然的に私たちは本当にこれらのサブクラスを実現する必要があります.
type Cat struct {
    MaxAge int
}

func (this *Cat) Sleep() {
    fmt.Println("Cat need sleep")
}
func (this *Cat) Age() int {
    return this.MaxAge
}
func (this *Cat) Type() string {
    return "Cat"
}
type Dog struct {
    MaxAge int
}

func (this *Dog) Sleep() {
    fmt.Println("Dog need sleep")
}
func (this *Dog) Age() int {
    return this.MaxAge
}
func (this *Dog) Type() string {
    return "Dog"
}

私たちは2つの具体的な実装クラスCat,Dogを持っていますが、AnimalはどのようにCatを知っていますか.Dogはそれを実現しましたか.なぜなら、Cat,DogはAnimalのすべての方法を実現し、それが私のサブクラスだと思っているからです.
では、この関係をどのように使うのでしょうか.
func Factory(name string) Animal {
    switch name {
    case "dog":
        return &Dog{MaxAge: 20}
    case "cat":
        return &Cat{MaxAge: 10}
    default:
        panic("No such animal")
    }
}

特定のファクトリクラスを使用して特定のインプリメンテーションクラスを構築し、呼び出し時にこれらの方法があることを知っていますが、特定のインプリメンテーションは分かりません.各タイプの変更は他のタイプに影響しません.
package main

import (
    "animals"
    "fmt"
)

func main() {
    animal := animals.Factory("dog")
    animal.Sleep()
    fmt.Printf("%s max age is: %d", animal.Type(), animal.Age())
}

出力を見てみましょう
> Output:
animals
command-line-arguments
Dog need sleep
Dog max age is: 20
> Elapsed: 0.366s
> Result: Success

これがgoの中の多態であり、implements/extendsが示す関係よりも優雅ではないか.