Last active
August 29, 2015 14:08
-
-
Save jrdalpra/07221f68a966f1762b89 to your computer and use it in GitHub Desktop.
Clean Architecture Ideas.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Processor<Request,Response> { | |
Response process(Request request); | |
} | |
class UserRepositoryThatUsesJPA implements UserRepository { | |
EntityManager entities; | |
Converter<User,UserEntity> toEntity; | |
Converter<UserEntity,User> toUser; | |
User save(User user){ | |
UserEntity entity = toEntity.convert(user); | |
if (entity.isNew()){ | |
entities.persist(entity); | |
return toUser.convert(entity); | |
} | |
UserEntity merged = entities.merge(entity); | |
return toUser.convert(merged); | |
} | |
} | |
class SaveNewUserProcessor implements Processor<SaveNewUser.Request, SaveNewUser.Response> { | |
UserRepository users; | |
Iterable<Validator<SaveNewUser.Request>> requestValidators | |
SaveNewUser.Response process(SaveNewUser.Request request){ | |
validate(request); | |
User newUser = request.getNewUser(); | |
User saved = users.save(newUser); | |
return new SaveNewUser.Response(saved); | |
} | |
validade(SaveNewUser.Request request) NotValid { | |
for(Validator<SaveNewUser.Request> validator : requestValidators) | |
validator.validate(request); | |
} | |
} | |
// I can implement alternatives or wrap | |
class LogArroundCallSaveNewUserProcessor implements Processor<SaveNewUser.Request, SaveNewUser.Response> { | |
Processor<SaveNewUser.Request, SaveNewUser.Response> officialImplementation; | |
SaveNewUser.Response process(SaveNewUser.Request request){ | |
log("before save " + request); | |
SaveNewUser.Response response = officialImplementation.process(request); | |
log("before send " + response); | |
return response; | |
} | |
} | |
// I can compose processors | |
class SaveNewProfile implements Processor<SaveNewProfile.Request, SaveNewProfile.Response> { | |
Processor<SaveNewUser.Request,SaveNewUser.Response> saveNewUser; | |
Processor<UploadPicture.Request,UploadPicture.Response> uploadPicture; | |
SaveNewProfile.Response process(SaveNewProfile.Request request){ | |
User savedUser = saveNewUser.process(new SaveNewUser.Request(request.getUserInfo())); | |
Picture uploadedPicture = uploadPicture.process(new UploadPicture.Request(request.getAttachedPicture())); | |
return new SaveNewProfile.Reponse(savedUser,uploadedPicture); | |
} | |
} | |
class ListUsersProcessors implements Processor<ListUsers.Request,ListUsers.Response>{ | |
UserRepository users; | |
ListUsers.Response process(ListUsers.Request request){ | |
PageOf<User> page = users.listBy(request.getCriteria()); | |
return new ListUsers.Response(page); | |
} | |
} | |
// I can iterate | |
class ChainOfProcessors { | |
Iterable<Processor<SaveNewUser.Request,SaveNewUser.Response>> processors; | |
SaveNewUser.Response process(SaveNewUser.Request request){ | |
for(processor : processors){ | |
// do something with each processor | |
} | |
} | |
} | |
// I can produce to user at CDI env | |
class ProcessorsProducer { | |
@Produces | |
@RequestScoped | |
@Inject | |
Processor<SaveNewUser.Request,SaveNewUser.Response> saveNewUser(UserRepository repository){ | |
return new SaveNewUserProcessor<>(repository); | |
// or compose return new LogArroundCallSaveNewUserProcessor<>(new SaveNewUserProcessor<>(repository)); | |
} | |
} | |
// I can use at REST endpoint | |
@Path("/users") | |
class UsersResource { | |
@Inject | |
Processor<SaveNewUser.Request,SaveNewUser.Response> saveNewUser; | |
@Inject | |
Processor<ListUsers.Request,ListUsers.Response> listUsers; | |
@Inject | |
Converter<PageOf<User>,List<UserResource>> toUserResources; | |
@Post | |
UserResource save(User user){ | |
SaveNewUserResponse response = saveNewUser.process(new SaveNewUser.Request(user)); | |
return new UserResource(response.getSaveUser()); | |
} | |
@Get | |
List<UserResource> list(Pagination pagination){ | |
return toUserResources.conver(listUsers.process(new ListUsers.Request(pagination)).getPageOfUsers()); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import java.util.List; | |
import lombok.RequiredArgsConstructor; | |
import lombok.val; | |
public class Test { | |
static interface Case<O> { | |
} | |
static interface Implementation<C extends Case<O>, O> { | |
O run(C case_); | |
} | |
@RequiredArgsConstructor(staticName = "where") | |
static class Clause { | |
Clause property(String name, Object value) { | |
return this; | |
} | |
} | |
static class Query { | |
static class One<E> implements Case<Return.One<E>> { | |
public One<E> using(Clause clause) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
} | |
static class Return { | |
static class One<E> { | |
E found; | |
} | |
public class PageOf<E> { | |
} | |
} | |
} | |
static class User { | |
String login; | |
String password; | |
@RequiredArgsConstructor(staticName = "query") | |
static class One extends Query.One<User> { | |
} | |
} | |
@RequiredArgsConstructor(staticName = "a") | |
static class Save<E> implements Case<Reponse<E>> { | |
public final E toSave; | |
public static <E> Save<E> an(E toSave) { | |
return a(toSave); | |
} | |
@RequiredArgsConstructor(staticName = "_") | |
static class Reponse<E> { | |
public final E saved; | |
} | |
} | |
@RequiredArgsConstructor(staticName = "some") | |
static class BatchSave<E> implements Case<Reponse<E>> { | |
public final List<E> toSave; | |
@RequiredArgsConstructor(staticName = "_") | |
static class Reponse<E> { | |
public final List<E> saved; | |
} | |
} | |
static class WarnAbout<E> implements Case<Void> { | |
E event; | |
} | |
private static Implementation<Save<User>, Save.Reponse<User>> users; | |
private static Implementation<Query.One<User>, Query.Return.One<User>> finder; | |
public static void main(String[] args) { | |
new Implementation<WarnAbout<User>, Void>() { | |
@Override | |
public Void run(WarnAbout<User> input) { | |
// TODO Auto-generated method stub | |
return null; | |
} | |
}; | |
val result = finder.run(User.One.query()); | |
if (result.found.login.equalsIgnoreCase("x")) | |
; | |
val response = users.run(Save.an(new User())); | |
System.out.println(response.saved); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment