2016-09-27 20 views
2

Google Cloud Datastore(またはGoogleアプリケーションエンジンのデータストア)を使用して、さまざまなオブジェクトを保存しています。これらのオブジェクトのほとんどは似ているので、私は多くのコードの重複で終わります。golangのインターフェイスでコードの重複を避ける

例として、2つの異なるオブジェクト(accountおよびindex)の2つの作成メソッドがあります。

func (account *Account) Create(ctx context.Context) (*Account, error) { 
    if ret, err := datastore.Put(ctx, account.newKey(ctx), account); err != nil { 
    log.Errorf(ctx, "Error while creating Account : %v\n", err) 
    return nil, err 
    } else { 
    account.Id = strconv.FormatInt(ret.IntID(), 10) 
    } 

    return account, nil 
} 

func (index *Index) Create(ctx context.Context) (*Index, error) { 
    if ret, err := datastore.Put(ctx, index.newKey(ctx), index); err != nil { 
    log.Errorf(ctx, "Error while creating Index : %v\n", err) 
    return nil, err 
    } else { 
    index.Id = strconv.FormatInt(ret.IntID(), 10) 
    } 

    return index, nil 
} 

あなたが見ることができるように、2つのスニペットは、ホルダータイプ、戻り値の型、およびエラーメッセージのexceptsで同一です。

このようなコードの重複を避けるための慣習的な方法は何ですか?

答えて

2

使用インタフェースは、私はこれを試した方法& SetID()

type Entity interface { 
    SetId(id int64) 
    NewKey(c context.Context) *datastore.Key 
} 

func create(c context.Context, entity Entity) error { 
    if ret, err := datastore.Put(c, entity.NewKey(c), entity); err != nil { 
    log.Errorf(c, "Error while creating entity: %v\n", err) 
    return err 
    } else { 
    entity.SetId(ret.IntID()) 
    return nil 
    } 
} 

func (index *Index) Create(c context.Context) (*Index, error) { 
    return index, create(c, index) 
} 

func (account *Account) Create(c context.Context) (*Account, error) { 
    return account, create(c, account) 
} 
+0

NewKey()を定義し、それは 'メソッドされていないcreate'機能を持っている不思議な感じ。なぜなら、私はいくつかの種類のエンティティを持つかもしれないからです。識別されたもの、および例えば、未確認のもの。そして、私はこれらの異なるエンティティに対して異なる方法で 'create'関数を実装する必要があります。 私はそれを各エンティティのためのメソッドにしたいと思っていましたが、それは混乱に終わった。 しかし、私は、メソッドに頼るのではなく、 'createIdedEnt'や' createUnidedEnt'のように、これらの関数の名前を別にしなければならないと思います。 – etnbrd

+0

私はエンティティからデータアクセス層を切り離すでしょう。 :AccountDal()。Create(ctx、account)。 –

関連する問題