ThreeDotsLabs / wild-workouts-go-ddd-example

Go DDD example application. Complete project to show how to apply DDD, Clean Architecture, and CQRS by practical refactoring.
https://threedots.tech
MIT License
5.04k stars 464 forks source link

Can we use a pointer for Repository assignment? #61

Open frederikhors opened 2 years ago

frederikhors commented 2 years ago

Given the repository in repository.go:

type Repository interface {
  AddTraining(ctx context.Context, tr *Training) error
  //...
}

we are creating new structs which implement that interface using code such as in trainings_firestore_repository.go:

type TrainingsFirestoreRepository struct {
  firestoreClient *firestore.Client
}

func NewTrainingsFirestoreRepository(
  firestoreClient *firestore.Client,
) TrainingsFirestoreRepository {
  return TrainingsFirestoreRepository{
    firestoreClient: firestoreClient,
  }
}

and we are create commands and queries with those structs, such as in service.go:


func newApplication(ctx context.Context, trainerGrpc command.TrainerService, usersGrpc command.UserService) app.Application {
  client, err := firestore.NewClient(ctx, os.Getenv("GCP_PROJECT"))
  //...
  trainingsRepository := adapters.NewTrainingsFirestoreRepository(client)
  //...
  return app.Application{
    Commands: app.Commands{
      ApproveTrainingReschedule: command.NewApproveTrainingRescheduleHandler(trainingsRepository, usersGrpc, trainerGrpc, logger, metricsClient),
      //...
    },
    Queries: app.Queries{
      AllTrainings:     query.NewAllTrainingsHandler(trainingsRepository, logger, metricsClient),
      //...
    },
  }
}

satisfying func signature like:

func NewApproveTrainingRescheduleHandler(
  repo training.Repository,
  //...
) decorator.CommandHandler[ApproveTrainingReschedule] {}

Question

In each func like command.NewApproveTrainingRescheduleHandler(trainingsRepository, /*...*/) we are passing trainingsRepository each time different (passed-by-value).

Can we use a pointer there avoiding maybe useless memory consumption?

m110 commented 2 years ago

Hey @frederikhors.

Sure, there's no issue with using pointers to repositories or other adapters. In most cases, you would find the effect on memory negligible, though. In the example above, the only field of the struct is a pointer, so copying it won't be noticeable in any way.

frederikhors commented 2 years ago

Ok. But I'm not able to use pointers. The compiler reject it. Can you try?

m110 commented 1 year ago

What error did you get? You will probably need to change some occurrences in the code to match pointers, but it should be straightforward.