spring-modulith icon indicating copy to clipboard operation
spring-modulith copied to clipboard

Thoughts on changing visibility of EventRepository-related classes to public

Open pcuriel opened this issue 1 year ago • 3 comments
trafficstars

Currently, different implementations of EventPublicationRepository and their related classes (e.g., JdbcEventPublicationRepository, JdbcEventPublicationRepository and its JpaEventPublication, MongoDbEventPublicationRepository and its MongoDbEventPublicationRepository, etc.) have package-protected visibility.

This makes it impossible to reuse any of these classes, and even for simple customizations the only alternative left is copying & pasting all the classes. Wouldn't it make more sense to change visibility to public, to ease extensibility?

pcuriel avatar Apr 15 '24 18:04 pcuriel

It could. That said, the current design considers the repository implementations an implementation detail of the EventPublicationRegistry and doesn't expect anyone to extend it. That, of course, doesn't have to stay that way, but I'd much rather open things up gradually as soon as we understand the actual needs for extension. Having everything open by default would mean we're unable to change a thing about them anymore, as there might be someone already compiling against the types. The repository interfaces have changed quite a bit since their inception.

Can you elaborate what the reuse would look like and why that would be the technology-specific interfaces and not the repository interface itself?

odrotbohm avatar Apr 16 '24 07:04 odrotbohm

For instance, a case where I think reusing existing implementation can be helpful is customizing the DB schema.

class CustomMongoDbEventPublicationRepository extends MongoDbEventPublicationRepository {

	/*
	 * Note: in this case, these two methods should be changed from static to instance too, apart from the visibility change.
	 */

	protected MongoDbEventPublication domainToDocument(TargetEventPublication publication) {

		return new CustomMongoDbEventPublication( //
				publication.getIdentifier(), //
				publication.getPublicationDate(), //
				publication.getTargetIdentifier().getValue(), //
				publication.getEvent(),
				// ... additional fields that apply
				);
	}

	protected TargetEventPublication documentToDomain(MongoDbEventPublication document) {
		return new CustomMongoDbEventPublicationAdapter((CustomMongoDbEventPublication) document);
	}

}

For this particular use case, could even be better if the repository implementation is defined like this:

public abstract class AbstractMongoDbEventPublicationRepository<DOCUMENT> {
  ...
}

class CustomMongoDbEventPublicationRepository extends AbstractMongoDbEventPublicationRepository<MongoDbEventPublication> {
}

In fact, maybe having a public Abstract Repository implementation and a package-private concrete one could be a solution for this problem you mention:

Having everything open by default would mean we're unable to change a thing about them anymore, as there might be someone already compiling against the types.

pcuriel avatar Apr 16 '24 19:04 pcuriel

@odrotbohm Another Scenario is managing the EventPublication as an Entity in jpa module

right now I am forced to create a duplicate entity for EventPublication to mirror the already created table and then manage the repository by exposing what I need.

I guess if the incomplete Events as is exposed List/Stream in the incompleteEventPublications interface would solve this image

the same way completedEventsPublications interface has a findAll() image

zikozee avatar May 08 '24 09:05 zikozee