views:

218

answers:

6

I am trying to use Bonjour from Java. I found an example of how to do it and I think I understood it. But I still do not understand why it should be done in such a complicated way. May be I miss something.

So, the code I found works in the following way (the code is also given bellow).

  1. Java program tries to find a service and if the service is found, the program tries to "resolve" the service (I think "to resolve a service" means "to use a service" or "to connect to a service").

  2. To "resolve" the found service we need to call "DNSSD.resolve" method and as the last argument of this method we need to give an object.

  3. "DNSSD.resolve" tries to resolve a given service. If "DNSSD.resolve" is able to resolve the service it calls "serviceResolved" method of the instance given as the last argument. If "DNSSD.resolve" is unable to resolve the service, ti calls "operationFailed" method of the above mentioned object.

Here is the code:

DNSSD.resolve(0, ifIndex, serviceName, regType, domain, new ResolveListener(){
                public void serviceResolved(DNSSDService resolver, int flags, int ifIndex,
                String fullname, String hostname, int port, TXTRecord txtRecord){
                    InetAddress theAddress;
                    try {
                        theAddress = InetAddress.getByName(hostname);
                    } catch (UnknownHostException e) {
                        // ouch..
                    }
                }

                public void operationFailed(DNSSDService arg0, int arg1) {
                    // ouch, again!
                }
            });

Would it be not simpler to organize the code in the following way.

  1. We call "DNSSD.resolve" method with information about the service we want to resolve.

  2. We do not pass any object to the "DNSSD.resolve".

  3. "DNSSD.resolve" do not call any method of any class.

  4. "DNSSD.resolve" tries to "resolve" a given service and, in the case it was able to do it, "DNSSD.resolve" returns true. Otherwise it returns false.

  5. The program runs either "serviceResolved" or "operationFailed" methods depending on the value returned by the "DNSSD.resolve".

Or I just did not get used to the OOP way of thinking?

+3  A: 

It's not so much "OOP way of thinking" as "asynchronous way of thinking". By using a callback function on an operation that might take a while, you can go off an do other things (or just keep your GUI responsive) while you're waiting for the operation to complete.

Paul Tomblin
But at which point do I introduce this "parallelism"? At some moment the program calls DNSSD.resolve and, I thought, that the calling program needs to wait till DNSSD resolve the service.
Roman
No, DNSSD.resolve() returns immediately, even though the resolution hasn't finished yet. Your program can go back to its main loop handling GUI events or whatever. When resolution finishes, your handler object gets called in a separate thread, and you can do some work with the results in that thread, or queue a message back to the GUI thread to show the results, etc.
Wyzard
+2  A: 

also that code is Java -> JNI -> C code. There isn't anything OO about it. It is async procedural code with a Java wrapper around it.

fuzzy lollipop
How do you see that it is "async"? What makes it "async"?
Roman
you call code and tell it what functions to call when the work is done instead of waiting for the results synchronously. I have looked at the Apple C code that this Java wrapper calls.
fuzzy lollipop
+3  A: 

Of course, there are a lot of different ways of approaching a "problem". The approach taken here is a callback approach: You call the resolve method and hand it a method (well, actually an object containing a method, because Java hasn't got anonymous methods or closures etc...). Once that resolver has (un-)successfully resolved whatever you wanted it to resolve, it will call the serviceResolved method you gave it (which then does something with the information the resolver offers).

That means that it is an asynchronous approach, but not OO. You can do something else while the Resolver is "working", the serviceResolved method will be called somewhen, so you do not need to wait for that.

Tedil
How can you see that "I can do something else while the Resolver working"? I thought that if I call a method, program will weight till method finishes its task and only after that the program will execute code given after the method.
Roman
Think of it this way: the method's job is not to actually resolve the service, it's just to start a thread that can resolve the service later. So yes, your program has to wait for the method to finish its task, but it doesn't have to wait for the service to be resolved.
Wyzard
+1  A: 

The JavaDoc of DNSSD.resolve states that "Most operations are non-blocking; clients are called back through an interface with the result of an operation. Callbacks are made from a separate worker thread."

http://developer.apple.com/mac/library/documentation/Java/Reference/DNSServiceDiscovery_JavaRef/com/apple/dnssd/DNSSD.html

That is where the parallelism comes from.

Christian Semrau
A: 

In JBonjourBrowser, you can see how the "asynchronous approach", cited by others, is used in a JTree subscriber model. The author's note that this "is especially helpful ... where devices are often very transient and services are announced and disappear shortly afterwards.

trashgod
A: 

The callback interface style is commonly used for asynchronous operation.

When designing an interface, especially services involved in network or IO operation, two questions come up frequently: 1. does the operation synchronous (blocking) or asynchronous (non-blocking) 2. does the operation return a value or not

We cannot say if an callback style is Object Oriented or not. Object oriented design is about assigning clear responsibility for each object.

In contrary, the callback mechanism is a very common pattern in OO design for asynchronous operation. 1. Service responsible for providing the prescribed service 2. Callback responsible to receiving response of the service

Zarick Lau