Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid code duplication with interface in golang

I am using the Google Cloud Datastore (or the google app engine datastore), to store different objects. Most of these objects are similar, hence I end up with lots of code duplication.

As an example, here are two create methods, of two different objects, account and index.

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
}

As you can see, the two snippets are identical, excepts for the holder type, the return type, and the error message.

What is the idiomatic way to avoid this kind of code duplication ?

like image 604
etnbrd Avatar asked Dec 02 '25 06:12

etnbrd


1 Answers

Use interface to define methods NewKey() & 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)
}
like image 138
Alexander Trakhimenok Avatar answered Dec 04 '25 02:12

Alexander Trakhimenok



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!