I have a question about asynchronous method calls in java, especially about the response value of the async method.
The situation is the following:
The async method I want to call is..
public void getSpeed(IResponseListener listener) {
....
}
The interface of the listener is...
interface IResponseListener {
public void response(ResponseEvent event);
}
This method is called when the async method has a response value
My problem now is that the class ResponseEvent has an attribute response that can be of any type (boolean,float,String...)and in the implementation of the interface IResponseListener I have to cast the value...
IResponseListener listener = new IResponseListener {
public void response(ResponseEvent event) {
float f = (float)event.response;
}
}
Is this a good solution to handle this? I think the bad thing is that the response listener HAS to know the type of the response!
Is there a better solution to handle asynchronous calls that want to give a response even if the response can be of any type?
I think a lot of these answers are starting to look like this->
public interface Function<Args, Value>
{
public Value call(Args args);
}
Your return type doesn't matter--if it can return multiple types, then the "multiple types" are a type...might I suggest a type of JSON considering what you're looking at?
The reality is you can't expect your handler to know the type in advance so you need to specify that. Whether this is with the return type or the class is up to you.
I could easily see doing a class hierarchy:
public class ResponseString implements Function<Args, String>;
public class ResponseNumber implements Function<Args, Number>;
...
public class ResponseType implements Function<Args, Type>;
or simply creating a type that has all the information you need. The long and short is that the method can DEFINE what it expects for the types and you have the ability to extend them. Keep in mind that response could also be a Function which could be executed. There's nothing wrong with knowing what to DO with something and not knowing what it is ->
Example->
//Admittedly I'd probably have a "Procedure or VoidFunction interface as well".
public yourMethod(Function<String args, Function<String,?> handler)
{
String hello = "hello";
Function<String,?> function = handler.call(hello);
function.call(hello);
}
I hope this helps. Sometimes there's no reason to go this far, and sometimes there is. You don't know the type--it seems like maybe you're hoping someone else will provide it and this can do that for you while remaining strict.
EDIT:
the example of have for this in one framework is:
Applcation.openDialog(Dialog dialog, Callable<Boolean> onClose);
This returns true of the dialog cleans up and closes and false if not. I don't really care what happens here, I do care that it tells me yes, close it, or no don't.
Use Java generics:
interface IResponseListener<T> {
public void response(T response);
}
Then, in an anonymous class:
IResponseListener listener = new IResponseListener<Float> {
public void response(Float response) {
float f = response;
}
}
I don't know whether this is correct, but if you are going to handle the return value differently, why not overload the response method with different type of objects that you would expect. Just a suggestion..
interface InterfaceName{
void response(float responseVal);
void response(boolean responseVal);
...
}
I would have done as #nico_ekito says...Or use your existing solution. It is a problem that you don't know the result type.
Anyway, you could do some adjustments and let the ResponseEvent class do the casting for you.
ResponseListener.java
interface IResponseListener {
void response(ResponseEvent event);
}
ResponseEvent.java
public class ResponseEvent {
private Object response;
#SuppressWarnings("unchecked")
public <T> T getResponse() {
return (T)response;
}
public <T> void setResponse(T response) {
this.response = response;
}
}
Usage:
IResponseListener listener = new IResponseListener() {
public void response(ResponseEvent event) {
float f = event.getResponse();
}
};
Please note that you will get a ClassCastException if your type is something other than what you expect it to be.
Related
Examle below must return user.photo_100 (and user.photo_100 response String, I logged it), but var wallPostUserAvatar set null. Looks like I missed something, but I can't find it out.
public class WallPostExtends {
private String wallPostUserAvatar;
public String getUserPhotoLink(int user_id){
//Prepare request for userName and photo
final VKRequest request = VKApi.users().get(VKParameters.from(VKApiConst.USER_ID, user_id, VKApiConst.FIELDS, "photo_100"));
request.executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onError(VKError error) {
}
#Override
public void onComplete(VKResponse response) {
super.onComplete(response);
//Work with UserName and photo response
VKApiUserFull user = ((VKList<VKApiUserFull>) response.parsedModel).get(0);
wallPostUserAvatar = user.photo_100;
}
});
Log.d("photo link: ", wallPostUserAvatar); //Here is NULL. What am I doing wrong?
return wallPostUserAvatar; //How to return here "user.photo_100" ?
}
}
I think i came to know the reason why wallPostUserAvatar is null , because the you are assigning the value in onComplete() and the execution flow is not how you think, the log you printed will be executed first and then depends on what is happening in executeWithListener() will execute after.
I have a solution for this, i will share with you.
You can use callback mechanism here.
A typical example would be using Interface
public interface Callbacks {
public void successCallback(String response);
public void failCallback(String response);
}
Then you can use this interface as follows:
public void getUserPhotoLink(int user_id,final Callbacks callback){
request.executeWithListener(new VKRequest.VKRequestListener() {
#Override
public void onError(VKError error) {
callbacks.failCallback("fail");
}
#Override
public void onComplete(VKResponse response) {
super.onComplete(response);
//Your code
callback.successCallback(user.photo_100);
}
Then you can call you function getUserPhotoLink() as
getUserPhotoLink(userid value,new Callbacks() {
#Override
public void successCallback(String success) {
//You will get your desired result here
}
#Override
public void failCallback(String fail) {
});
Hope it will help you
I don't know the VKApi, but it looks like its an asynchronous call based on the name and the fact you pass in a listener. That means you CANT return the string, because you won't have it until the asynchronous call completes. Instead you'd need to do any processing of it in onComplete.
In short:
Sorry to tell you, but you cannot return any value right there.
The VKRequestListener is called asynchronously, while the method returns immediately.
You will have to find a more suitable solution for this, like handing over the object you want to make the String accessable to and call a set-Method in the onComplete block.
If this is not being run on the UI thread, try putting a while(wallPostUserAvatar!=null); after the call to the log function. This would work because, as is, you probably have a race condition between the return and the API request and the return statement will almost always win that race.
Task: I am designing a library which will be used by developers.
Objective: I need to make sure that changes in future versions will not impact existing developers.
Example:
Situation during first release:
There is one class
public class ClassSample
{
String methodSample(String para1,String Para2, int Para3, String Para4);
}
Situation during second release:
Requirements:
Response of methodSample can return multiple values.
More parameters are needed in methodSample method.
Solution: One way could be just add another overloaded method which will have new parameters and return object rather than built-in data type.
But problem with above solution is, it will have too many overloaded methods in future, too many parameters will be overkill.
Modified Solution 1:
void methodSample(Request request, Response response)
In each release(obviously if required), I will modify Request & Response classes to have new additional methods to get/set values. There will be a problem in this case as inside the method, I won't be able to differentiate whether caller is of Version10 or Version20.
Modified Solution 2:
void methodSample(AbsractRequest request, AbstractResponse response)
In each release we can extend derived class like Request200 extends Request100 extends AbstractRequest, similarly for response classes. In this case I can check inside method whether caller is of Version10 or Version20 by checking instance typing.
In summary Modified Solution 2 looks good to me, what about your thoughts ?
I would go for Modified Solution 1, but with the addition of a get/set Version method in the class.
Your library can the use getVersion find out which behaviour the user program is expecting
I realise this might be a bit late but thought might be useful to you or someone else.
I've created an SDK in the past that required versioning and did something very similar to what I posted below and it worked a treat.
The idea being that all messages derive from an abstracted class as you suggested, but there is a static that is set in the calling application right at the start. All requests then simply set a Version property equal to that of the static. This way its only specified once in the whole application.
When you add new versions, just add to the enum. I actually used an integer in mine and incremented it but I think an Enum is always more maintainable.
Enjoy!
namespace SilverlightClassLibrary1
{
public enum SDKVersions
{
NonSpecific = 0,
Version100,
Version200,
}
public abstract class RequestBase
{
public static SDKVersions SystemSDKVersion { get; set; }
public SDKVersions RequestSDKVersion { get; set; }
protected RequestBase()
{
this.RequestSDKVersion = RequestBase.SystemSDKVersion;
}
}
public class SimpleDataRequest : RequestBase
{
public String Data { get; set; }
}
public class SimpleDataResponse
{
public String Response { get; set; }
}
public class SomeSDKFunctionality
{
public static void RandomSDKFunction(SimpleDataRequest request, out SimpleDataResponse response)
{
switch (request.RequestSDKVersion)
{
case SDKVersions.Version100:
//Legacy response
response = new SimpleDataResponse()
{
Response = "Helo " + request.Data,
};
break;
default:
//Fixed / Updated Response
response = new SimpleDataResponse()
{
Response = "Hello " + request.Data + "!",
};
break;
}
}
}
}
namespace MyExternalApplication
{
public class Main
{
public void ApplicationEntryPoint()
{
//Specify a specific version you intend to use
RequestBase.SystemSDKVersion = SDKVersions.Version100;
}
public void ButtonClickExample()
{
SimpleDataResponse response;
SomeSDKFunctionality.RandomSDKFunction(new SimpleDataRequest()
{
Data = "James",
}, out response);
}
}
}
I have enum say ErrorCodes that
public enum ErrorCodes {
INVALID_LOGIN(100),
INVALID_PASSWORD(101),
SESSION_EXPIRED(102) ...;
private int errorCode;
private ErrorCodes(int error){
this.errorCode = error;
} //setter and getter and other codes
}
now I check my exception error codes with this error codes. I don't want to write if this do this, if this do this. How I can solve this problem (writing 10+ if blocks)
Is there any design patter to that situation ?
Thanks
Either you do it with a if-statement or a switch, or you just implement the logic in question into the ErrorCode somehow.
In an OO fashion it all depends on how you want the application or system react to the error code. Lets say you just want it to output somekind of dialog:
public doSomethingWithError() {
ErrorCodes e = getError();
// the source of error, or originator, returns the enum
switch(e) {
case ErrorCodes.INVALID_LOGIN:
prompt('Invalid Login');
case ErrorCodes.INVALID_PASSWORD:
prompt('Invalid password');
// and so on
}
}
We could instead create an ErrorHandler class that does this instead:
// We'll implement this using OO instead
public doSomethingWithError() {
ErrorHandler e = getError();
// the originator now returns an ErrorHandler object instead
e.handleMessage();
}
// We will need the following abstract class:
public abstract class ErrorHandler {
// Lets say we have a prompter class that prompts the message
private Prompter prompter = new Prompter();
public final void handleMessage() {
String message = this.getMessage();
prompter.prompt(message);
}
// This needs to be implemented in subclasses because
// handleMessage() method is using it.
public abstract String getMessage();
}
// And you'll have the following implementations, e.g.
// for invalid logins:
public final class InvalidLoginHandler() {
public final String getMessage() {
return "Invalid login";
}
}
// E.g. for invalid password:
public final class InvalidPasswordHandler() {
public final String getMessage() {
return "Invalid password";
}
}
The former solution is easy to implement, but becomes difficult to maintain as the code grows larger. The latter solution is more complex, (aka. Template Method pattern following the Open-Closed Principle) but enables you to add more methods into the ErrorHandler when you need it (such as restoring resources or whatever). You can also implement this with the Strategy pattern.
You won't get away completely with the conditional statements, but in the latter the conditional is pushed to the part of the code where the error is originated. That way you won't have double maintenance on conditional statements both at the originator and the error handling code.
EDIT:
See this answer by Michael Borgwardt and this answer by oksayt for how to implement methods on Java Enums if you want to do that instead.
Java enums are very powerful and allow per-instance method implementations:
public enum ErrorCode {
INVALID_LOGIN {
public void handleError() {
// do something
}
},
INVALID_PASSWORD {
public void handleError() {
// do something else
}
},
SESSION_EXPIRED {
public void handleError() {
// do something else again
}
};
public abstract void handleError();
}
Then you can simply call errorCode.handleError();. However, it is questionable whether an ErrorCode enum is really the right place for that logic.
As pointed out by Spoike, using polymorphism to pick the right error handling method is an option. This approach basically defers the 10+ if blocks to the JVM's virtual method lookup, by defining a class hierarchy.
But before going for a full-blown class hierarchy, also consider using enum methods. This option works well if what you plan to do in each case is fairly similar.
For example, if you want to return a different error message for each ErrorCode, you can simply do this:
// Note singular name for enum
public enum ErrorCode {
INVALID_LOGIN(100, "Your login is invalid"),
INVALID_PASSWORD(101, "Your password is invalid"),
SESSION_EXPIRED(102, "Your session has expired");
private final int code;
private final String
private ErrorCode(int code, String message){
this.code = code;
this.message = message;
}
public String getMessage() {
return message;
}
}
Then your error handling code becomes just:
ErrorCode errorCode = getErrorCode();
prompt(errorCode.getMessage());
One drawback of this approach is that if you want to add additional cases, you'll need to modify the enum itself, whereas with a class hierarchy you can add new cases without modifying existing code.
I believe the best you can do is implementing the strategy pattern. This way you won't have to change existing classes when adding new enums but will still be able to extend them. (Open-Closed-Principle).
Search for Strategy Pattern and Open Closed Principle.
You can create a map of error codes(Integer) against enum types
Edit
In this solution, once the map is prepared, you can look up an error code in the map and thus will not require if..else look ups.
E.g.
Map<Integer, ErrorCodes> errorMap = new HashMap<Integer, ErrorCodes>();
for (ErrorCodes error : ErrorCodes.values()) {
errorMap.put(error.getCode(), error);
}
Now when you want to check an error code coming from your aplpication, all you need to do is,
ErrorCodes error = errorMap.get(erro_code_from_application);
Thus removing the need for all the if..else.
You just need to set up the map in a way that adding error codes doesn't require changes in other code. Preparation of the map is one time activity and can be linked to a database, property file etc during the initialization of your application
In my opinion there is nothing wrong with ErrorCodes as enums and a switch statement to dispatch error handling. Enums and switch fit together really well.
However, maybe you find the following insteresting (kind of over-design), see an Example
or "Double dispatching" on Wikipedia.
Assumed requirements:
Error-handling should be encapsulated in an own class
Error-handling should be replacable
Type safety: Whenever an error is added, you are forced to add error handling at each error-handler implementation. It is not possible to "forget" an error in one (of maybe many) switch statments.
The code:
//Inteface for type-safe error handler
interface ErrorHandler {
void handleInvalidLoginError(InvalidLoginError error);
void handleInvalidPasswordError(InvalidLoginError error);
//One method must be added for each kind error. No chance to "forget" one.
}
//The error hierachy
public class AbstractError(Exception) {
private int code;
abstract public void handle(ErrorHandler);
}
public class InvalidLoginError(AbstractError) {
private String additionalStuff;
public void handle(ErrorHandler handler) {
handler.handleInvalidLoginError(this);
}
public String getAdditionalStuff();
}
public class InvalidPasswordError(AbstractError) {
private int code;
public void handle(ErrorHandler handler) {
handler.handleInvalidPasswordError(this);
}
}
//Test class
public class Test {
public void test() {
//Create an error handler instance.
ErrorHandler handler = new LoggingErrorHandler();
try {
doSomething();//throws AbstractError
}
catch (AbstractError e) {
e.handle(handler);
}
}
}
In Moritz Haarmann's Blog I found an example of usage of Bonjour by Java. Here is the code taken from there:
public class ServiceAnnouncer implements IServiceAnnouncer, RegisterListener {
private DNSSDRegistration serviceRecord;
private boolean registered;
public boolean isRegistered(){
return registered;
}
public void registerService() {
try {
serviceRecord = DNSSD.register(0,0,null,"_killerapp._tcp", null,null,1234,null,this);
} catch (DNSSDException e) {
// error handling here
}
}
public void unregisterService(){
serviceRecord.stop();
registered = false;
}
public void serviceRegistered(DNSSDRegistration registration, int flags,String serviceName, String regType, String domain){
registered = true;
}
public void operationFailed(DNSSDService registration, int error){
// do error handling here if you want to.
}
}
I have a question about the "serviceRegistered" method. As far as I understand it is called during (or after) registration of the service (and it sets variable "registered" to be equal to "true"). But what is not clear to me is how exactly it is called. Because the service is registered by the method "registerService". This method, in its turn, calls "DNSSD.register". And, as far as I understand, the "DNSSD.register" will call the "serviceRegister" method of the "ServiceAnnouncer" class. But how "DNSSD.register" knows that it needs to call a method of the "ServiceAnnouncer" class? Can "DNSSD.register" know that it is called from a particular class (in this case "ServiceAnnouncer" class)?
The ServiceAnnouncer has passed itself as last argument of the DNSSD.register() method, which in turn is apparently expecting any instance of RegisterListener. This way the DNSSD can have a direct handle to the ServiceAnnouncer instance.
It seems that this class is a listener - namely RegisterListener. It has been registered as a listener in DNSSD by passing itself to the register(..) method.
For more information read about the Observer pattern.
I have the following situation where a client class executes different behavior based on the type of message it receives. I'm wondering if there is a better way of doing this since I don't like the instanceof and the if statements.
One thing I thought of doing was pulling the methods out of the client class and putting them into the messages. I would put a method like process() in the IMessage interface and then put the message specific behavior in each of the concrete message types. This would make the client simple because it would just call message.process() rather than checking types. However, the only problem with this is that the behavior contained in the conditionals has to do with operations on data contained within the Client class. Thus, if I did implement a process method in the concrete message classes I would have to pass it the client and I don't know if this really makes sense either.
public class Client {
messageReceived(IMessage message) {
if(message instanceof concreteMessageA) {
concreteMessageA msg = (concreteMessageA)message;
//do concreteMessageA operations
}
}
if (message instanceof concreteMessageB) {
concreteMessageb msg = (concreteMessageB)message;
//do concreteMessageB operations
}
}
The simple way to avoid instanceof testing is to dispatch polymorphicly; e.g.
public class Client {
void messageReceived(IMessage message) {
message.doOperations(this);
}
}
where each message class defines an appropriate doOperations(Client client) method.
EDIT: second solution which better matches the requirements.
An alternative that replaces a sequence of 'instanceof' tests with a switch statement is:
public class Client {
void messageReceived(IMessage message) {
switch (message.getMessageType()) {
case TYPE_A:
// process type A
break;
case TYPE_B:
...
}
}
}
Each IMessage class needs to define an int getMessageType() method to return the appropriate code. Enums work just as well ints, and are more more elegant, IMO.
One option here is a handler chain. You have a chain of handlers, each of which can handle a message (if applicable) and then consume it, meaning it won't be passed further down the chain. First you define the Handler interface:
public interface Handler {
void handle(IMessage msg);
}
And then the handler chain logic looks like:
List<Handler> handlers = //...
for (Handler h : handlers) {
if (!e.isConsumed()) h.handle(e);
}
Then each handler can decide to handle / consume an event:
public class MessageAHandler implements Handler {
public void handle(IMessage msg) {
if (msg instanceof MessageA) {
//process message
//consume event
msg.consume();
}
}
}
Of course, this doesn't get rid of the instanceofs - but it does mean you don't have a huge if-elseif-else-if-instanceof block, which can be unreadable
What type of message system are you using?
Many have options to add a filter to the handlers based on message header or content. If this is supported, you simply create a handler with a filter based on message type, then your code is nice and clean without the need for instanceof or checking type (since the messaging system already checked it for you).
I know you can do this in JMS or the OSGi event service.
Since you are using JMS, you can basically do the following to register your listeners. This will create a listener for each unique message type.
String filterMsg1 = "JMSType='messageType1'";
String filterMsg2 = "JMSType='messageType2'";
// Create a receiver using this filter
Receiver receiverType1 = session.createReceiver(queue, filterMsg1);
Receiver receiverType2 = session.createReceiver(queue, filterMsg2);
receiverType1.setMessageHandler(messageType1Handler);
receiverType2.setMessageHandler(messageType2Handler);
Now each handler will receive the specific message type only (no instanceof or if-then), assuming of course that the sender sets the type via calls to setJMSType() on the outgoing message.
This method is built into message, but you can of course create your own header property and filter on that instead as well.
//Message.java
abstract class Message{
public abstract void doOperations();
}
//MessageA.java
class MessageA extends Message{
public void doOperations(){
//do concreteMessageA operations ;
}
}
//MessageB.java
class MessageB extends Message {
public void doOperations(){
//do concreteMessageB operations
}
}
//MessageExample.java
class MessageExample{
public static void main(String[] args) {
doSmth(new MessageA());
}
public static void doSmth(Message message) {
message.doOperations() ;
}
}
A Java 8 solution that uses double dispatch. Doesn't get rid of instanceof completely but does only require one check per message instead of an if-elseif chain.
public interface Message extends Consumer<Consumer<Message>> {};
public interface MessageA extends Message {
#Override
default void accept(Consumer<Message> consumer) {
if(consumer instanceof MessageAReceiver){
((MessageAReceiver)consumer).accept(this);
} else {
Message.super.accept(this);
}
}
}
public interface MessageAReceiver extends Consumer<Message>{
void accept(MessageA message);
}
With JMS 2.0 you can use:
consumer.receiveBody(String.class)
For more information you can refer here: