Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break up the repository into multiple traits #100

Open
monksy opened this issue Nov 14, 2018 · 5 comments
Open

Break up the repository into multiple traits #100

monksy opened this issue Nov 14, 2018 · 5 comments

Comments

@monksy
Copy link

monksy commented Nov 14, 2018

A lot of the logic in the repositories looks replicated throughout all of the repositories. This may be better to break this up into reusable traits.

I.e.:

OrderService extends ... with Creatable[t] with Deleteable[T] with Updateable[T]

@zakpatterson
Copy link
Collaborator

This makes sense to me just for standardizing across multiple types of data.

Is there a function we would write that would only rely on an instance of Creatable or Deletable?

Here's one I came up with that saves an object, does some operation, and then cleans it up.

trait Creatable[F[_], T]{
  def create(t: T) : F[Unit]
}

trait Deletable[F[_], T] {
  def delete(t : T) : F[Unit]
}

object example{
  def withAThing[M[_], T, R](f : T => M[R])(implicit
    G : Gen[T],   // scalacheck
    C : Creatable[M, T],
    D : Deletable[M, T],
    E : MonadError[M, Throwable]
  ) : M[R] = for {
    example <- G.sample.liftTo[M](new AssertionError("Example not generated"))
    _ <- C.create(example)
    result <- f(example)
    _ <- D.delete(example)
  } yield result
}

There's also the issue about how to generalize/standardize across just data generated by the database. I've played with this a bit in another project:

CRUDAlgebra/CRUDService:
https://github.com/clovellytech/h4sm/tree/master/db/src/main/scala/h4sm/db

Example typeclass extending CRUDAlgebra:
https://github.com/clovellytech/h4sm/blob/master/auth/src/main/scala/h4sm/auth/domain/users/UserRepositoryAlgebra.scala

Example instance of the typeclass:
https://github.com/clovellytech/h4sm/blob/master/auth/src/main/scala/h4sm/auth/infrastructure/repository/persistent/UserRepositoryInterpreter.scala

@monksy
Copy link
Author

monksy commented Nov 14, 2018

That's an interesting idea. However, the only thing I have a question about is how would you make those attributes stackable? I.e. if you had a caching or notification layer on each of those operations?

@zakpatterson
Copy link
Collaborator

Hm perhaps by an interesting choice of F it could be done? I think working an example of such a thing would be good.

@pauljamescleary
Copy link
Owner

It is an interesting idea. I like the idea of a CRUD algebra, because you assume you have to create/update/delete/getById on everything.

@monksy
Copy link
Author

monksy commented Nov 19, 2018

I like that because the CRUD operations vary from service to service. Some services don't have deletes, some have getById, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants