Reputation: 7219
I have built a software architecture and now I wonder if it can be considered to match some knowed design pattern:
All layers are composed of multiple interfaces that contain small pieces of logic:
HasService
indicates that a class contains an EntityService
implementation of some E
and Q
type.
public interface HasService<E extends BaseEntity, Q extends QueryParams> {
EntityService<E, Q> getService();
}
InsertDtoEndpoint
indicates that a class has the ability to receive a json input formated as D
, map it to E
, insert it and then map it back to D
before return it.
public interface InsertDtoEndpoint<E extends AbstractBaseEntity, D extends Dto, Q extends QueryParams>
extends Endpoint, HasService<E, Q> {
@POST
default Response insert(D dto) {
return ok(executeInsert(dto));
}
default D executeInsert(D dto) {
E mapped = mapInsertRequestRecordToPersistentEntity(dto);
return mapInsertResponseRecordToDto(getService().save(mapped));
}
E mapInsertRequestRecordToPersistentEntity(D dto);
D mapInsertResponseRecordToDto(E entity);
}
Then the actual endpoints which are accessed via http calls are composed of a composition of these interfaces:
public class SomeEntityEndpoint implements InsertDtoEndpoint<SomeEntity, SomeDto, DefaultQueryParam>, FetchEndpoint<SomeEntity, DefaultQueryParams>, FindEndpoint<SomeEntity, DetailedDto, DefaultQueryParams> {
SomeEntity mapInsertRequestRecordToPersistentEntity(SomeDto dto) {
//map to entity
}
SomeDto mapInsertResponseRecordToDto(SomeEntity entity) {
//map to dto
}
DetailedDto mapFindResponseRecordToDto(SomeEntity entity) {
//Map to dto
}
getService() {
//Return service..
}
}
Upvotes: 0
Views: 157
Reputation: 20185
First, let it be mentioned that there are different levels of patterns. I am not speaking about the types (like creational, structural, behavioural...) but the actual impact on your codebase. On the one hand, there are Patterns like the Marker Interface Pattern (basically an empty interface) which have little to no impact on your code. On the other hand, there are patterns like Abstract Factory Pattern and Builder Pattern, which have a major impact on your overall design.
Your code shows basic decoupling by implementing interfaces. Thus if it follows a pattern, it would be one of the "smaller" patterns.
The Strategy Pattern you mentioned is based on decoupled code. But the core of the Strategy Pattern is that you change the strategy while the program is running. An example would be changing the AI of some game (let's pick StarCraft for the sake of it) in response to recognising that the opponent is significantly weakter/stronger and a more defensive/offensive behaviour would be beneficial. Your code seems to implement some web-service (or at least some data transfers between processes). Normally you do not re-define how your object is transferred, so I would not call this a Strategy Pattern.
As you mentioned in the comments, the Template Method Pattern would fit. Your server defines when to send what (or at least, this is how I imagine it) and calls the concrete Endpoints to delegate the actual work.
Overall, labeling your code with pattern names is not the goal. You should choose the right tool for the job. Some patterns are more suitable for some tasks than others. Sometimes a solution following none of the known patterns may even be more elegant/readable/performant/whatever your metric is. In this case, do not try to squeeze your solution in a pattern just to have this big fancy name tag on top of it (this usually leads to over-engeneering). Sometimes, simple code is more elegant than every pattern.
Upvotes: 2