Remove duplication with AbstractBehavior.createReceive - java

when implementing an Akka Typed actor by extending createReceive, we will see something like this:
#Override
public Receive<Command> createReceive()
{
return newReceiveBuilder()
.onMessage(SomeCommand.class, s -> something())
.build();
}
..with something() returning a Behavior, for example:
public Behavior<Command> something()
{
return Behaviors.receive(Command.class)
.onMessage(SomeCommand.class, m -> something())
.build();
}
But now we can see that createReceive() and something() being pretty much duplicates. In other words, whenever I return to the "initial" state, I will get this code duplication. So, the question is:
Can I somehow implement createReceive() by re-using the something() method? For example, is something like this possible...
#Override
public Receive<Command> createReceive()
{
return Behaviors.behave( this::something);
}
(Of course, Behaviors.behave does not exist like this, the question is, does something like this exists, "converting" a Behavior to a receive?)

Akka 2.7.0 will introduce an alternative API for defining a behavior which is basically a port of the Scala API.
public class MyActor extends AbstractOnMessageBehavior<MyActor.Command>
public static interface Command {}
public static class SomeCommand extends Command {
public static SomeCommand INSTANCE = new SomeCommand();
private SomeCommand() {}
}
public MyActor(ActorContext<Command> context) {
super(context);
}
#Override
public Behavior<Command> onMessage(Command msg) {
if (msg instanceof SomeCommand) { return something((SomeCommand)msg); }
else return Behaviors.unhandled();
}
private Behavior<Command> something(SomeCommand sc) {
// FIXME: actually do something useful
return Behaviors.same()
}
}
(Apologies if the Java is atrocious)
This API is likely slightly lower overhead than the current Java AbstractBehavior API: the ReceiveBuilder and BehaviorBuilder APIs are effectively compiling a domain-specific language like:
newReceiveBuilder()
.onMessage(SomeMessage.class, this::something)
.build()
into
if (msg instanceof SomeMessage) { return something((SomeMessage)msg); }
else return Behaviors.unhandled();
whenever an instance of this behavior handles its first message (i.e. when an actor handles its first message after transitioning to this behavior). When staying in this behavior, there's also some overhead of checking if the Receive has been built already (though JIT may largely eliminate that).
The benefit of the ReceiveBuilder/BehaviorBuilder APIs is that the instanceof checks and casts are hidden: the developer ergonomic improvement is worth some small overhead. The AbstractOnMessageBehavior lets you opt out of the builder APIs:
You can, effectively, manually compile the builder into instanceof and cast like I did above (this will work on any Java version); if you're on Java 8/11 and want max performance, this might be worth trying (but always, always, benchmark!)
You can use language features ("pattern matching") to have the Java compiler build the instanceof-and-cast logic... this should also make it easier to define a behavior in Kotlin or other JVM language which supports pattern matching. This might even be more ergonomic than the builders.
You can also use a different approach entirely (e.g. one leveraging virtual method dispatch)

Related

How to build a custom intermediate operation pipeline in Java for a series of API calls?

I am working on a project which provides a list of operations to be done on an entity, and each operation is an API call to the backend. Let's say the entity is a file, and operations are convert, edit, copy. There are definitely easier ways of doing this, but I am interested in an approach which allows me to chain these operations, similar to intermediate operations in java Streams, and then when I hit a terminal operation, it decides which API call to execute, and performs any optimisation that might be needed. My API calls are dependent on the result of other operations. I was thinking of creating an interface
interface operation{
operation copy(Params ..); //intermediate
operation convert(Params ..); // intermediate
operation edit(Params ..); // intermediate
finalresult execute(); // terminal op
}
Now each of these functions might impact the other based on the sequence in which the pipeline is created. My high level approach would be to just save the operation name and params inside the individual implementation of operation methods and use that to decide and optimise anything I'd like in the execute method. I feel that is a bad practice since I am technically doing nothing inside the operation methods, and this feels more like a builder pattern, while not exactly being that. I'd like to know the thoughts on my approach. Is there a better design for building operation pipelines in java?
Apologies if the question appears vague, but I am basically looking for a way to build an operation pipeline in java, while getting my approach reviewed.
You should look at a pattern such as
EntityHandler.of(remoteApi, entity)
.copy()
.convert(...)
.get();
public class EntityHandler {
private final CurrentResult result = new CurrentResult();
private final RemoteApi remoteApi;
private EntityHandler(
final RemoteApi remoteApi,
final Entity entity) {
this.remoteApi = remoteApi;
this.result.setEntity(entity);
}
public EntityHandler copy() {
this.result.setEntity(new Entity(entity)); // Copy constructor
return this;
}
public EntityHandler convert(final EntityType type) {
if (this.result.isErrored()) {
throw new InvalidEntityException("...");
}
if (type == EntityType.PRIMARY) {
this.result.setEntity(remoteApi.convertToSecondary(entity));
} else {
...
}
return this:
}
public Entity get() {
return result.getEntity();
}
public static EntityHandler of(
final RemoteApi remoteApi,
final Entity entity) {
return new EntityHandler(remoteApi, entity);
}
}
The key is to maintain the state immutable, and handle thread-safety on localized places, such as in CurrentResult, in this case.

Are guards to check if a method has been called optimized by Java?

Consider the following code:
public class BasicBuildOrder {
private List<GameObject> gameObjects = new ArrayList<>();
private List<GameObject> savedState;
public void saveState() {
savedState = new ArrayList<>(gameObjects);
}
public void resetToSavedState() {
if (savedState == null) {
throw new IllegalStateException("the state has not been saved");
}
gameObjects = savedState;
}
public void add(GameObject gameObject) {
gameObjects.add(gameObject);
}
public void get(int index) {
return gameObjects.get(index);
}
public void remove(GameObject gameObject) {
gameObjects.remove(gameObject);
}
}
I am implementing a pattern where you can mark a list as saved in some particular state, and later restore that state. I'm aware that the current way of saving/resetting is a bit shady and gives O(n) performance whereas that could be improved by tagging which items have been added, retrieved, removed.
Now an issue I see is that a call to resetToSavedState() will be done before a call to saveState(), hence I need to check for that.
My question is: Is the if (savedState == null) check at some point optimized away by Java (either by the compiler, or at runtime) if it knows that saveState() has been called and hence savedState cannot be null anymore?
Additional question, is there a pattern available for this methodA-called-before-methodB relation?
It cannot be optimized when compiling Java source to .class-files. It can be optimized in runtime by JIT compiler if both saveState() and resetToSavedState() are called from the same method and both are inlined there during the JIT compilation (or some deeper call-chain is fully inlined). Inlining is quite possible here as saveState() and resetToSavedState() are very simple. After that both become parts of the outer method in which after building control-flow graph and value analysis it might become possible to determine that no control paths go into the if statement, so such CFG edges will be pruned. However you should not rely that this will occur.
In general you cannot reliably predict the program order just looking at the program code (without actually executing it). However extra null check means almost nothing in terms of performance, so you should not worry about it.
Is the if (savedState == null) check at some point optimized away by Java (either by the compiler, or at runtime) if it knows that saveState() has been called and hence savedState cannot be null anymore?
Neither the JVM, not the JIT optimizes this away completely (in future it might). However, the CPU can use branch prediction to assume the check will be false and thus has almost no impact. i.e. < 1 ns.
There is a pattern for this "methodA-called-before-methodB relation", and you can even encode it into the type-system.
Consider fluid APIs for Builders. That seems to be encapsulating your problem perfectly and even without doing runtime checks:
public class BasicBuildOrder {
protected List<GameObject> gameObjects = new ArrayList<>();
public static class SavedBuildOrder extends BasicBuildOrder {
private List<GameObject> savedState;
private SavedBuildOrder(Collection<GameObject> gameObjects) {
savedState = new ArrayList<>(gameObjects);
}
public void resetToSavedState() {
gameObjects = savedState;
}
}
public SavedBuildOrder saveState() {
return new SavedBuildOrder(gameObjects);
}
public void add(GameObject gameObject) {
gameObjects.add(gameObject);
}
public void get(int index) {
return gameObjects.get(index);
}
public void remove(GameObject gameObject) {
gameObjects.remove(gameObject);
}
}
An alternative to this rather clunky workaround would be something like the Memento Pattern.
In either case, Tagir Valeev, Oliver Charlesworth and Filipp are probably correct anyways:
However, null check should be pretty cheap even without compiler
magic. - Filipp
However extra null check means almost nothing in terms of performance,
so you should not worry about it. - Tagir
Unless it can be shown via static analysis that the method is always
called, then some kind of runtime information must be used. Thus some
kind of check must be performed. - Oliver

Do I use Java lambda appropriately for this strategy pattern?

I use lambda expression + Function to implement a strategy pattern, do I use it correctly and appropriately ?
public void deploy(WatcherConfig config) {
performOnWatch(config, a -> {
deployWatch(a);
return null;
});
}
public void delete(final WatcherConfig config) {
performOnWatch(config, a -> {
deleteWatch(a);
return null;
});
}
public void performOnWatch(WatcherConfig config, Function<WatchConfig, Void> function) {
for (WatchConfig watchConfig : config.getWatchConfigs()) {
List<WatchConfig> realConfigs = WatchUtils.parseWatchParameter(watchConfig);
for(WatchConfig realWatchConfig : realConfigs) {
function.apply(realWatchConfig);
}
}
}
You could simplify the performOnWatch method using streams if you implement a streamWatchConfigs to replace getWatchConfigs (which presumably returns a collection):
public void performOnWatch(WatcherConfig config, Consumer<WatchConfig> consumer) {
config.streamWatchConfigs()
.flatMap(WatchUtils::parseWatchParameters)
.forEach(consumer::accept);
}
performOnWatch(config, this::deployWatch);
performOnWatch(config, this::deleteWatch);
Every time you are using the word "pattern" you are digging yourself into a terrible mental hole. That's why I wish that pattern book was never written. Stop thinking about patterns. Forget their names. Think in terms of what you need to get done and what tools the language gives you to solve the problem in a way that combines flexibility, readability of the code and performance. Patterns are mental crutches. If you are smart enough to use patterns correctly, you don't need patterns. IF you are not, patterns will hurt you more than help you.
Seems legit. The only thing I would change is using Consumer<WatchConfig> instead of Function<WatchConfig, Void>. It will simplify method signatures as well as strategy implementations (there will be no need to return null from strategy).
Also if deleteWatch() and deployWatch() returns null and if you will use Consumer code can be rewritten as:
performOnWatch(config, this::deployWatch);
performOnWatch(config, this::deleteWatch);

alternative to instanceof operator when specifying mocks for multiple web services

I am writing endpoint unit tests and for most of those there is an external web service that should be mocked, or a couple of them.
At first, i was creating mocks within tests which was okay when an endpoint test used only one external service, the mock creation was basically one liner.
As use cases became more complex, i needed to mock couple of services and exceptions for a single endpoint test.
I have put these mocks creation behind factories that all extend single factory and used builder pattern.
Within that base factory there is an inner class which i used as a builder for MockWebServiceServer.
protected class MultiStepMockBuilder {
private List<Object> mockActions = new ArrayList<Object>();
private WebServiceGatewaySupport gatewaySupport;
protected MultiStepMockBuilder(WebServiceGatewaySupport gatewaySupport) {
this.gatewaySupport = gatewaySupport;
}
protected MultiStepMockBuilder exception(RuntimeException exception) {
mockActions.add(exception);
return this;
}
protected MultiStepMockBuilder resource(Resource resource) {
mockActions.add(resource);
return this;
}
protected MockWebServiceServer build() {
MockWebServiceServer server = MockWebServiceServer.createServer(gatewaySupport);
for(Object mock: mockActions) {
if (mock instanceof RuntimeException) {
server.expect(anything()).andRespond(withException((RuntimeException)mock));
}
else if (mock instanceof Resource)
{
try
{
server.expect(anything()).andRespond(withSoapEnvelope((Resource) mock));
} catch (IOException e) {e.printStackTrace();}
}
else
throw new RuntimeException("unusuported mock action");
}
return server;
}
}
}
So i can now do something like this to create mock:
return new MultiStepMockBuilder(gatewaySupport).resource(success).exception(new WebServiceIOException("reserve timeout"))
.resource(invalidMsisdn)
.build();
The issue i have with this implementation is dependence on instanceof operator which i never use outside of equals.
Is there an alternative way to instanceof operator in this scenario ? From the questions on topic of instanceof everybody argues it should only be used within equals and therefore i have feeling that this is 'dirty' solution.
Is there an alternative to instanceof operator, within Spring or as a different design, while keeping fluent interface for mocks creation ?
I don't know Spring well enough to comment specifically on this particular area, but to me, this just seems like a design thing. Generally, when you are faced with using instanceof, it means that you need to know the type, but you don't have the type. It is generally the case that we might need to refactor in order to achieve a more cohesive design that avoids this kind of problem.
The root of where the type information is being lost, is in the List of mock actions, which are currently just being stored as a List of Objects. One way to help with this then, is to look at the type of the List and consider if there is a better type that could be stored in the List that might help us later. So we might end up with a refactoring something like this.
private List<MockAction> mockActions = new ArrayList<MockAction>();
Of course, then we have to decide what a MockAction actually is, as we've just made it up. Maybe something like this:
interface MockAction {
void performAction(MockWebServiceServer server);
}
So, we've just created this MockAction interface, and we've decided that instead of the caller performing the action - we're going to pass the server into it and ask the MockAction to perform itself. If we do this, then there will be no need for instanceof - because particular types of MockActions will know what they contain.
So, what types of MockActions do we need?
class ExceptionAction implements MockAction {
private final Exception exception;
private ExceptionAction(final Exception exception) {
this.exception = exception;
}
public void performAction(final MockWebServiceServer server) {
server.expect(anything()).andRespond(withException(exception);
}
}
class ResourceAction implements MockAction {
private final Resource resource;
private ResourceAction(final Resource resource) {
this.resource = resource;
}
public void performAction(final MockWebServiceServer server) {
/* I've left out the exception handling */
server.expect(anything()).andRespond(withSoapEnvelope(resource));
}
}
Ok, so now we've gotten to this point, there are a couple of loose ends.
We're still adding exceptions to the list of MockActions - but we need to change the add methods to make sure we put the right thing in the list. The new versions of these methods might look something like this:
protected MultiStepMockBuilder exception(RuntimeException exception) {
mockActions.add(new ExceptionAction(exception));
return this;
}
protected MultiStepMockBuilder resource(Resource resource) {
mockActions.add(new ResourceAction(resource));
return this;
}
So, now we've left our interface the same, but we're wrapping the resource or exception as they're added to the list so that we have the type specificity we need later on.
And then finally, we need to refactor our method that actually makes the calls, which now looks something like this - which is much simpler and cleaner.
protected MockWebServiceServer build() {
MockWebServiceServer server = MockWebServiceServer.createServer(gatewaySupport);
for(MockAction action: mockActions) {
action.performAction(server);
}
return server;
}

Best design pattern/approach for a long list of if/else/execute branches of code

I have a "legacy" code that I want to refactor.
The code basically does a remote call to a server and gets back a reply. Then according to the reply executes accordingly.
Example of skeleton of the code:
public Object processResponse(String responseType, Object response) {
if(responseType.equals(CLIENT_REGISTERED)) {
//code
//code ...
}
else if (responseType.equals(CLIENT_ABORTED)) {
//code
//code....
}
else if (responseType.equals(DATA_SPLIT)) {
//code
//code...
}
etc
The problem is that there are many-many if/else branches and the code inside each if is not trivial.
So it becomes hard to maintain.
I was wondering what is that best pattern for this?
One thought I had was to create a single object with method names the same as the responseType and then inside processResponse just using reflection call the method with the same name as the responseType.
This would clean up processResponse but it moves the code to a single object with many/many methods and I think reflection would cause performance issues.
Is there a nice design approach/pattern to clean this up?
Two approaches:
Strategy pattern http://www.dofactory.com/javascript/strategy-design-pattern
Create dictionary, where key is metadata (in your case metadata is responseType) and value is a function.
For example:
Put this in constructor
responses = new HashMap<string, SomeAbstraction>();
responses.Put(CLIENT_REGISTERED, new ImplementationForRegisteredClient());
responses.Put(CLIENT_ABORTED, new ImplementationForAbortedClient());
where ImplementationForRegisteredClient and ImplementationForAbortedClient implement SomeAbstraction
and call this dictionary via
responses.get(responseType).MethodOfYourAbstraction(SomeParams);
If you want to follow the principle of DI, you can inject this Dictionary in your client class.
My first cut would be to replace the if/else if structures with switch/case:
public Object processResponse(String responseType, Object response) {
switch(responseType) {
case CLIENT_REGISTERED: {
//code ...
}
case CLIENT_ABORTED: {
//code....
}
case DATA_SPLIT: {
//code...
}
From there I'd probably extract each block as a method, and from there apply the Strategy pattern. Stop at whatever point feels right.
The case you've describe seems to fit perfectly to the application of Strategy pattern. In particular, you've many variants of an algorithm, i.e. the code executed accordingly to the response of the remote server call.
Implementing the Stategy pattern means that you have to define a class hierachy, such the following:
public interface ResponseProcessor {
public void execute(Context ctx);
}
class ClientRegistered implements ResponseProcessor {
public void execute(Context ctx) {
// Actions corresponding to a client that is registered
// ...
}
}
class ClientAborted implements ResponseProcessor {
public void execute(Context ctx) {
// Actions corresponding to a client aborted
// ...
}
}
// and so on...
The Context type should contain all the information that are needed to execute each 'strategy'. Note that if different strategies share some algorithm pieces, you could also use Templeate Method pattern among them.
You need a factory to create a particular Strategy at runtime. The factory will build a strategy starting from the response received. A possibile implementation should be the one suggested by #Sattar Imamov. The factory will contain the if .. else code.
If strategy classes are not to heavy to build and they don't need any external information at build time, you can also map each strategy to an Enumeration's value.
public enum ResponseType {
CLIENT_REGISTERED(new ClientRegistered()),
CLIENT_ABORTED(new ClientAborted()),
DATA_SPLIT(new DataSplit());
// Processor associated to a response
private ResponseProcessor processor;
private ResponseType(ResponseProcessor processor) {
this.processor = processor;
}
public ResponseProcessor getProcessor() {
return this.processor;
}
}

Categories