My issue is how to organize the code. Let say I have a User class
public class User extends RealmObject {
#PrimaryKey
private String id;
#Required
private String name;
public User() { // per requirement of no args constructor
id = UUID.randomUUID().toString();
}
// Assume getter & setter below...
}
and a Util class is needed to handles the save in an asynchronous manner since RealmObjects cannot have methods other than getter/setter.
public class Util {
public static void save(User user, Realm realm) {
RealmAsyncTask transaction = realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.copyToRealm(user); // <====== Argument needs to be declared final in parent method's argument!
}
}, null);
}
}
The intention is to put save() in a Util class to prevent spreading similar save code all over the code-base so that every time I wanted to save I would just call it as such:
User u = new User();
u.setName("Uncle Sam");
Util.save(u, Realm.getDefaultInstance());
Not sure if this affects performance at all, but I was just going to save all fields overwriting what was there except for the unique id field every single time.
The problem is that I now need to set the "user" argument as final in the Util.save() method, which means I cannot pass in the object I need to save other than once.
Is there a different way of handling this? Maybe a different pattern? Or am I looking at this all wrong and should go back to SQLite?
Why is it a problem to set public static void save(final User user, Realm realm) ? It just means you cannot reassign the user variable to something else.
That said, the existence of a save() method can be a potential code smell as you then spread the update behaviour across the code base. I would suggest looking into something like the Repository pattern (http://martinfowler.com/eaaCatalog/repository.html) instead.
Realm is actually working on an example showing how you can combine the Model-View-Presenter architecture with a Repository to encapsulate updates which is a good pattern for what you are trying to do here. You can see the code for it here: https://github.com/realm/realm-java/pull/1960
Related
My Spring Boot application implements a Service class which is passed a request object from a RestController. This service method is responsible for updating an entity.
As there are a lot of fields to be updated, I separated the updating logic into several private methods for better readability like this:
#Transactional
public void updateUser(UserRequest userRequest) {}
final User user = userRepository.findById(userRequest.getId).orElseThrow(() -> new EntityNotFoundException()));
updateUserFromRequest(user, userRequest);
}
private void updateUserFromRequest(User user, UserRequest userRequest) {
updateUserMainData(user, userRequest);
updateUserAdditionalData(user, userRequest);
}
private void updateUserMainData(User user, UserRequest userRequest) {
user.setProperty1(userRequest.getProperty1());
user.setProperty2(userRequest.getProperty2());
user.setProperty3(userRequest.getProperty3());
}
private void updateUserAdditionalData(User user, UserRequest userRequest) {
user.setProperty4(userRequest.getProperty4());
user.setProperty5(userRequest.getProperty5());
user.setProperty6(userRequest.getProperty6());
}
While this works just fine, it feels "awkward" to pass around the User object into private methods. Is this apporach considered "good practice" or are there any other patterns?
One possibility could be hiding this complexity in the User class itself by adding an update(UserRequest userRequest) method. No more User being passed around into private methods (which could be considerer to have side effects).
If you don't want to add logic to your entity class, another possibility to make it less "awkward" would be to have all the updateXXXX() methods returning the updated User. Of course, this changes nothing in practical terms but it hints that the User was indeed updated in the method, reducing a little bit the "methods with side-effect" feeling.
Update: The issue seems to be the id that I'm using twice, or in other words, the id from the product entity that I want to use for the productinventory entity. As soon as I generate a new id for the productinventory entity, it seems to work fine. But I want to have the same id for both, since they're the same product.
I have 2 Services:
ProductManagementService (saves a Product entity with product details)
1.) For saving the Product Entity, I implemented an EventHandler that listens to ProductCreatedEvent and saves the product to a mysql database.
ProductInventoryService (saves a ProductInventory entity with stock quantities of product to a certain productId defined in ProductManagementService )
2.) For saving the ProductInventory Entity, I also implemented an EventHandler that listens to ProductInventoryCreatedEvent and saves the product to a mysql database.
What I want to do:
When a new Product is created in ProductManagementService, I want to create a ProductInventory entity in ProductInventoryService directly afterwards and save it to my msql table. The new ProductInventory entity shall have the same id as the Product entity.
For that to accomplish, I created a Saga, which listes to a ProductCreatedEvent and sends a new CreateProductInventoryCommand. As soon as the CreateProductInventoryCommand triggers a ProductInventoryCreatedEvent, the EventHandler as described in 2.) should catch it. Except it doesn't.
The only thing thta gets saved is the Product Entity, so in summary:
1.) works, 2.) doesn't. A ProductInventory Aggregate does get created, but it doesn't get saved since the saving process that is connected to an EventHandler isn't triggered.
I also get an Exception, the application doesn't crash though: Command 'com.myApplication.apicore.command.CreateProductInventoryCommand' resulted in org.axonframework.commandhandling.CommandExecutionException(OUT_OF_RANGE: [AXONIQ-2000] Invalid sequence number 0 for aggregate 3cd71e21-3720-403b-9182-130d61760117, expected 1)
My Saga:
#Saga
#ProcessingGroup("ProductCreationSaga")
public class ProductCreationSaga {
#Autowired
private transient CommandGateway commandGateway;
#StartSaga
#SagaEventHandler(associationProperty = "productId")
public void handle(ProductCreatedEvent event) {
System.out.println("ProductCreationSaga, SagaEventHandler, ProductCreatedEvent");
String productInventoryId = event.productId;
SagaLifecycle.associateWith("productInventoryId", productInventoryId);
//takes ID from product entity and sets all 3 stock attributes to zero
commandGateway.send(new CreateProductInventoryCommand(productInventoryId, 0, 0, 0));
}
#SagaEventHandler(associationProperty = "productInventoryId")
public void handle(ProductInventoryCreatedEvent event) {
System.out.println("ProductCreationSaga, SagaEventHandler, ProductInventoryCreatedEvent");
SagaLifecycle.end();
}
}
The EventHandler that works as intended and saves a Product Entity:
#Component
public class ProductPersistenceService {
#Autowired
private ProductEntityRepository productRepository;
//works as intended
#EventHandler
void on(ProductCreatedEvent event) {
System.out.println("ProductPersistenceService, EventHandler, ProductCreatedEvent");
ProductEntity entity = new ProductEntity(event.productId, event.productName, event.productDescription, event.productPrice);
productRepository.save(entity);
}
#EventHandler
void on(ProductNameChangedEvent event) {
System.out.println("ProductPersistenceService, EventHandler, ProductNameChangedEvent");
ProductEntity existingEntity = productRepository.findById(event.productId).get();
ProductEntity entity = new ProductEntity(event.productId, event.productName, existingEntity.getProductDescription(), existingEntity.getProductPrice());
productRepository.save(entity);
}
}
The EventHandler that should save a ProductInventory Entity, but doesn't:
#Component
public class ProductInventoryPersistenceService {
#Autowired
private ProductInventoryEntityRepository productInventoryRepository;
//doesn't work
#EventHandler
void on(ProductInventoryCreatedEvent event) {
System.out.println("ProductInventoryPersistenceService, EventHandler, ProductInventoryCreatedEvent");
ProductInventoryEntity entity = new ProductInventoryEntity(event.productInventoryId, event.physicalStock, event.reservedStock, event.availableStock);
System.out.println(entity.toString());
productInventoryRepository.save(entity);
}
}
Product-Aggregate:
#Aggregate
public class Product {
#AggregateIdentifier
private String productId;
private String productName;
private String productDescription;
private double productPrice;
public Product() {
}
#CommandHandler
public Product(CreateProductCommand command) {
System.out.println("Product, CommandHandler, CreateProductCommand");
AggregateLifecycle.apply(new ProductCreatedEvent(command.productId, command.productName, command.productDescription, command.productPrice));
}
#EventSourcingHandler
protected void on(ProductCreatedEvent event) {
System.out.println("Product, EventSourcingHandler, ProductCreatedEvent");
this.productId = event.productId;
this.productName = event.productName;
this.productDescription = event.productDescription;
this.productPrice = event.productPrice;
}
}
ProductInventory-Aggregate:
#Aggregate
public class ProductInventory {
#AggregateIdentifier
private String productInventoryId;
private int physicalStock;
private int reservedStock;
private int availableStock;
public ProductInventory() {
}
#CommandHandler
public ProductInventory(CreateProductInventoryCommand command) {
System.out.println("ProductInventory, CommandHandler, CreateProductInventoryCommand");
AggregateLifecycle.apply(new ProductInventoryCreatedEvent(command.productInventoryId, command.physicalStock, command.reservedStock, command.availableStock));
}
#EventSourcingHandler
protected void on(ProductInventoryCreatedEvent event) {
System.out.println("ProductInventory, EventSourcingHandler, ProductInventoryCreatedEvent");
this.productInventoryId = event.productInventoryId;
this.physicalStock = event.physicalStock;
this.reservedStock = event.reservedStock;
this.availableStock = event.availableStock;
}
}
What you are noticing right now is the uniqueness requirement of the [aggregate identifier, sequence number] pair within a given Event Store. This requirement is in place to safe guard you from potential concurrent access on the same aggregate instance, as several events for the same aggregate all need to have a unique overall sequence number. This number is furthermore use to identify the order in which events need to be handled to guarantee the Aggregate is recreated in the same order consistently.
So, you might think this would opt for a "sorry there is no solution in place", but that is luckily not the case. There are roughly three things you can do in this set up:
Life with the fact both aggregates will have unique identifiers.
Use distinct bounded contexts between both applications.
Change the way aggregate identifiers are written.
Option 1 is arguably the most pragmatic and used by the majority. You have however noted the reuse of the identifier is necessary, so I am assuming you have already disregarded this as an option entirely. Regardless, I would try to revisit this approach as using UUIDs per default for each new entity you create can safe you from trouble in the future.
Option 2 would reflect itself with the Bounded Context notion pulled in by DDD. Letting the Product aggregate and ProductInventory aggregate reside in distinct contexts will mean you will have distinct event stores for both. Thus, the uniqueness constraint would be kept, as no single store is containing both aggregate event streams. Whether this approach is feasible however depends on whether both aggregates actually belong to the same context yes/no. If this is the case, you could for example use Axon Server's multi-context support to create two distinct applications.
Option 3 requires a little bit of insight in what Axon does. When it stores an event, it will invoke the toString() method on the #AggregateIdentifier annotated field within the Aggregate. As your #AggregateIdentifier annotated field is a String, you are given the identifier as is. What you could do is have typed identifiers, for which the toString() method doesn't return only the identifier, but it appends the aggregate type to it. Doing so will make the stored aggregateIdentifier unique, whereas from the usage perspective it still seems like you are reusing the identifier.
Which of the three options suits your solution better is hard to deduce from my perspective. What I did do, is order them in most reasonable from my perspective.
Hoping this will help your further #Jan!
Currently, my notification request is like this:
public class EmailRequest{
public enum EmailType{
TYPE_1,
TYPE_2,
...
}
EmailType emailType;
String toAddress;
EmailRenderer renderer;
}
where EmailRenderer is an interface
public interface EmailRenderer{
EmailMessage render()
}
Now, each type of email has a separate implementation of the renderer interface and each implementation contains some rendering data that has to be provided by the client. This data can be different for each implementation.
Example:
public class Type1EmailRenderer implements EmailRenderer{
String param1;
String param2;
#Override
EmailMessage render(){
//rendering logic using the params
}
}
But, it seems redundant to me for the user to set the email type and renderer as well. Choosing the renderer should automatically get me the emailType. How should I restructure the request to be free of this redundancy? Also, can I use any design pattern for providing the renderers to my users?
I'll base my answer on a claim that,
putting aside programming-related questions, at the level of human logic, it looks to me strange that if I want to send an email I should know about renderers at all.
In my understanding If I have emails of different types (you've called them TYPE_1 and TYPE_2, let's give more "business" names for better clarity, like "dailyReport" or "advertisement", you'll see later why) I should just prepare a request with my data (param1, param2) and send it. I shouldn't care about renderers at all as long as the same email type assumes that the same type of renderer will be used.
So, lets say, type "advertisement" has a mandatory parameter String topic and optional parameter String targetAudience and type "dailyReport" has Integer totalUsersCount and optional String mostActiveUserName.
In this case, I propose the somewhat hybrid approach mainly based on Builder creation pattern:
public class EmailRequestBuilder {
private String toAddress;
private EmailRequestBuilder(String to) {
this.toAddress = to;
}
public static EmailRequestBuilder newEmailRequest(String to) {
return new EmailRequestBuilder(to);
}
public AdvertisementBuilder ofAdvertisementType(String topic) {
return new AdvertisementBuilder(topic, this);
}
public DailyReportBuilder ofDailyReportType(Integer totalUsersCount) {
return new DailyReportBuilder(totalUsersCount, this);
}
// all builders in the same package, hence package private build method,
// concrete email type builders will call this method, I'll show at the end
EmailRequest build(EmailType type, EmailRenderer emailRenderer) {
return new EmailRequest (to, type, emailRenderer);
}
}
public class AdvertisementBuilder {
private String topic;
private EmailRequestBuilder emailRequestBuilder;
// package private, so that only EmailRequestBuilder will be able to create it
AdvertisementBuilder(String topic, EmailRequestBuilder emailRequestBuilder) // mandatory parameters in constructor + reference to already gathered data {
this.topic = topic;
this.emailRequestBuilder = emailRequestBuilder;
}
// for optional parameters provide an explicit method that can be called
// but its not a mandatory call
public AdvertisementBuilder withTargetAudience(String audience) {
this.audience = audience;
return this;
}
public EmailRequest buildRequest() {
EmailRenderer renderer = new AdvertisementRenderer(topic, audience);
return emailRequestBuilder.build(EmailType.ADVERTISEMENT, renderer);
}
}
// A similar builder for DailyReport (I'll omit it but assume that there is a class
class DailyReportBuilder {}
Now the good part about it that now you can't go wrong as a user. A typical interaction with such a construction will be:
EmailRequest request = EmailRequestBuilder.newEmailRequest("john.smith#gmail.com")
.ofAdvertisementType("sample topic") // its a mandatory param, you have to supply, can't go wrong
.withTargetAudience("target audience") // non-mandatory call
.buildRequest();
Couple of notes:
Once you pick a type by calling ofDailyReportType/ ofAdvertisementType the user can't really supply parameters of different email type, because it gets "routed" to the builder that doesn't have methods for wrong parameters. An immediate implication of this is that an autocomplete will work in your IDE and people who will use this method will thank you about it ;)
It's easy to add new email types this way, no existing code will change.
Maybe with this approach, an enum EmailType will be redundant. I've preserved it in my solution but probably you'll drop it if it's not required.
Since I sometimes restrict the visibility (package private build methods, constructors, and so forth) - it will be __the_only__way to create the request which means that no-one will create "internal" objects only because it's possible to do so. At least a malicious programmer will think twice before breaking encapsulation :)
For example you can use "factory method".
EmailRenderer createRenderer(EmailType type) {
switch (type) {
case: TYPE_1:
return new RendererType1();
case: TYPE_2:
return new RendererType2();
...
}
}
Also, you probably can introduce cashing of this objects in order not to create them every time. Maybe some lazy initialization (you create appropriate Renderer first time when you needed and after that always return that same instance).
I need to unit test a method, and I would like mock the behavior so that I can test the necessary part of the code in the method.
For this I would like access the object returned by a private method inside the method I am trying to test. I created a sample code to give a basic idea of what I am trying to achieve.
Main.class
Class Main {
public String getUserName(String userId) {
User user = null;
user = getUser(userId);
if(user.getName().equals("Stack")) {
throw new CustomException("StackOverflow");
}
return user.getName();
}
private User getUser(String userId) {
// find the user details in database
String name = ""; // Get from db
String address = ""; // Get from db
return new User(name, address);
}
}
Test Class
#Test (expected = CustomException.class)
public void getUserName_UserId_ThrowsException() {
Main main = new Main();
// I need to access the user object returned by getUser(userId)
// and spy it, so that when user.getName() is called it returns Stack
main.getUserName("124");
}
There are only two ways to access private:
using reflection
extend the scope
maybe waiting for Java 9 to use new scope mechanisms?
I would change the scope modifier from private to package scope. Using reflection is not stable for refactoring. It doesn't matter if you use helpers like PowerMock. They only reduce the boiler-plate code around reflection.
But the most important point is you should NOT test too deep in whitbox tests. This can make the test setup explode. Try to slice your code into smaller pieces.
The only information the method "getUserName" needs from the User-object is the name. It will validate the name and either throw an exception or return it. So it should not be necessary to introduce a User-object in the test.
So my suggestion is you should extract the code retreiving the name from the User-object into a separate method and make this method package scope. Now there is no need to mock a User-Object just the Main-Object. But the method has its minimal information available to work properly.
class Main {
public String getUserName(String userId) {
String username = getUserNameFromInternal(userId);
if (userName.equals("Stack")) {
throw new CustomException("StackOverflow");
}
return user.getName();
}
String getUserNameFromInternal(String userId) {
User user = getUser(userId);
return user.getName();
}
...
}
The test:
#Test (expected = CustomException.class)
public void getUserName_UserId_ThrowsException() {
Main main = Mockito.mock(new Main());
Mockito.when(main.getUserNameInternal("124")).thenReturn("Stack");
main.getUserName("124");
}
Your problem that call to new within your private method.
And the answer is not to turn to PowerMock; or to change the visibility of that method.
The reasonable answer is to "extract" that dependency on "something that gives me a User object" into its own class; and provide an instance of that class to your "Main" class. Because then you are able to simply mock that "factory" object; and have it do whatever you want it to do.
Meaning: your current code is simply hard-to-test. Instead of working around the problems that are caused by this, you invest time in learning how to write easy-to-test code; for example by watching these videos as a starting point.
Given your latest comment: when you are dealing with legacy code, then you are really looking towards using PowerMockito. The key part to understand: you don't "mock" that private method; you rather look into mocking the call to new User() instead; as outlined here.
You can use a PowerMock's mockPrivate but I don't recommend it.
If you has such a problem it usually mean that your design is bad.
Why not making the method protected?
Our application is getting complex, it has mainly 3 flow and have to process based on one of the 3 type. Many of these functionalities overlap each other.
So currently code is fully of if-else statements, it is all messed up and not organised. How to make a pattern so that 3 flows are clearly separated from each other but making use of power of re-usability.
Please provide some thoughts, this is a MVC application, where we need to produce and consume web servicees using jaxb technology.
May be you can view the application as a single object as input on which different strategies needs to be implemented based on runtime value.
You did not specify what your if-else statements are doing. Say they filtering depending on some value.
If I understand your question correctly, you want to look at Factory Pattern.
This is a clean approach, easy to maintain and produces readable code. Adding or removing a Filter is also easy, Just remove the class and remove it from FilterFactory hashmap.
Create an Interface : Filter
public interface Filter {
void Filter();
}
Create a Factory which returns correct Filter according to your value. Instead of your if-else now you can just use the following :
Filter filter = FilterFactory.getFilter(value);
filter.filter();
One common way to write FilterFactory is using a HashMap inside it.
public class FilterFactory{
static HashMap<Integer, Filter> filterMap;
static{
filterMap = new HashMap<>();
filterMap.put(0,new Filter0());
...
}
// this function will change depending on your needs
public Filter getFilter(int value){
return filterMap.get(value);
}
}
Create your three(in your case) Filters like this: (With meaningful names though)
public class Filter0 implements Filter {
public void filter(){
//do something
}
}
NOTE: As you want to reuse some methods, create a FilterUtility class and make all your filters extend this class so that you can use all the functions without rewriting them.
Your question is very broad and almost impossible to answer without some description or overview of the structure of your application. However, I've been in a similar situation and this is the approach I took:
Replace conditions with Polymorphism where possible
it has mainly 3 flow and have to process based on this one of the 3
type. Many of these functionalities overlap each other.
You say your project has 3 main flows and that much of the code overlaps each other. This sounds to me like a strategy pattern:
You declare an interface that defines the tasks performed by a Flow.
public interface Flow{
public Data getData();
public Error validateData();
public void saveData();
public Error gotoNextStep();
}
You create an abstract class that provides implementation that is common to all 3 flows. (methods in this abstract class don't have to be final, but you definitely want to consider it carefully.)
public abstract class AbstractFlow{
private FlowManager flowManager
public AbstractFlow(FlowManager fm){
flowManager = fm;
}
public final void saveData(){
Data data = getData();
saveDataAsXMl(data);
}
public final Error gotoNextStep(){
Error error = validateData();
if(error != null){
return error;
}
saveData();
fm.gotoNextStep();
return null;
}
}
Finally, you create 3 concrete classes that extend from the abstract class and define concrete implementation for the given flow.
public class BankDetailsFlow extends AbstractFlow{
public BankDetailsData getData(){
BankDetailsData data = new BankDetailsData();
data.setSwiftCode(/*get swift code somehow*/);
return data;
}
public Error validateData(){
BankDetailsData data = getData();
return validate(data);
}
public void onFormSubmitted(){
Error error = gotoNextStep();
if(error != null){
handleError(error);
}
}
}
Lets take example, suppose you have model say "Data" [which has some attributes and getters,setters, optional methods].In context of Mobile application ,in particular Android application there can be two modes Off-line or On-line. If device is connected to network , data is sent to network else stored to local database of device.
In procedural way someone can , define two models as OnlineData,OfflineData and write code as[The code is not exact ,its just like pseudo code ]:
if(Connection.isConnected()){
OnlineData ond=new OnlineData();
ond.save();//save is called which stores data on server using HTTP.
}
else{
OfflineData ofd=new Onlinedata();
ofd.save();//save is called which stores data in local database
}
A good approach to implement this is using OOPS principles :
Program to interface not Implementation
Lets see How to DO THIS.
I am just writing code snippets that will be more effectively represent what I mean.The snippets are as follows:
public interface Model {
long save();//save method
//other methods .....
}
public class OnlineData extends Model {
//attributes
public long save(){
//on-line implementation of save method for Data model
}
//implementation of other methods.
}
public class OfflineData extends Model {
//attributes
public long save(){
//off-line implementation of save method for Data model
}
//implementation of other methods.
}
public class ObjectFactory{
public static Model getDataObject(){
if(Connection.isConnected())
return new OnlineData();
else
return new OfflineData();
}
}
and Here is code that your client class should use:
public class ClientClass{
public void someMethod(){
Model model=ObjectFactory.getDataObject();
model.save();// here polymorphism plays role...
}
}
Also this follows:
Single Responsibility Principle [SRP]
because On-line and Off-line are two different responsibilities which we can be able to integrate in Single save() using if-else statement.
After loong time I find opensource rule engine frameworks like "drools" is a great alternative to fit my requirement.