Java 为什么要这么复杂呢?这是OOP的思维方式吗?

Java 为什么要这么复杂呢?这是OOP的思维方式吗?,java,bonjour,zeroconf,Java,Bonjour,Zeroconf,我正在尝试使用Java中的Bonjour。我找到了一个如何做的例子,我想我明白了。但我仍然不明白为何要这样复杂。也许我错过了什么 因此,代码按以下方式工作(下面也给出了代码) Java程序尝试查找服务,如果找到了服务,程序将尝试“解析”服务(我认为“解析服务”的意思是“使用服务”或“连接到服务”) 要“解析”找到的服务,我们需要调用“DNSSD.resolve”方法,并且作为该方法的最后一个参数,我们需要给出一个对象 “DNSSD.resolve”尝试解析给定的服务。如果“DNSSD.resol

我正在尝试使用Java中的Bonjour。我找到了一个如何做的例子,我想我明白了。但我仍然不明白为何要这样复杂。也许我错过了什么

因此,代码按以下方式工作(下面也给出了代码)

  • Java程序尝试查找服务,如果找到了服务,程序将尝试“解析”服务(我认为“解析服务”的意思是“使用服务”或“连接到服务”)

  • 要“解析”找到的服务,我们需要调用“DNSSD.resolve”方法,并且作为该方法的最后一个参数,我们需要给出一个对象

  • “DNSSD.resolve”尝试解析给定的服务。如果“DNSSD.resolve”能够解析服务,它将调用作为最后一个参数给出的实例的“servicesolved”方法。如果“DNSSD.resolve”无法解析服务,ti将调用上述对象的“operationFailed”方法

  • 代码如下:

    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!
                    }
                });
    
    以下面的方式组织代码不是更简单吗

  • 我们调用“DNSSD.resolve”方法,其中包含有关要解析的服务的信息

  • 我们不会将任何对象传递给“DNSSD.resolve”

  • “DNSSD.resolve”不调用任何类的任何方法

  • “DNSSD.resolve”尝试“解析”给定的服务,如果它能够做到这一点,“DNSSD.resolve”返回true。否则返回false

  • 程序运行“servicesolved”或“operationFailed”方法,具体取决于“DNSSD.resolve”返回的值


  • 或者我只是不习惯OOP思维方式?

    与其说是“OOP思维方式”,不如说是“异步思维方式”。通过对一个可能需要一段时间的操作使用回调函数,您可以在等待操作完成时执行其他操作(或只是保持GUI响应)。

    该代码也是Java->JNI->C代码。这件事一点也不糟糕。这是一个异步过程代码,周围有一个Java包装器。

    当然,处理“问题”有很多不同的方法。这里采用的方法是回调方法:调用resolve方法并将其交给一个方法(实际上是一个包含方法的对象,因为Java没有匿名方法或闭包等)。 一旦解析程序(取消)成功解析了您希望它解析的内容,它将调用您提供给它的
    servicesolved
    方法(然后使用解析程序提供的信息执行某些操作)


    这意味着它是一种异步方法,但不是OO。您可以在解析器“工作”时执行其他操作,
    servicesolved
    方法将在某个时候调用,因此您无需等待。

    DNSSD.resolve的JavaDoc声明“大多数操作是非阻塞的;客户端通过一个接口被回调,并返回操作结果。回调是从单独的工作线程进行的。”


    这就是并行性的来源。

    在中,您可以看到其他人引用的“异步方法”是如何在
    JTree
    订户模型中使用的。。。在这里,设备通常是非常短暂的,服务会被宣布,然后很快就会消失

    回调接口样式通常用于异步操作

    在设计接口时,尤其是涉及网络或IO操作的服务时,经常会出现两个问题: 1.操作是同步(阻塞)还是异步(非阻塞) 2.该操作是否返回值

    我们不能说回调样式是否是面向对象的。 面向对象的设计是为每个对象分配明确的责任

    相反,回调机制是面向对象异步操作设计中非常常见的模式。 1.负责提供规定服务的服务
    2.负责接收服务响应的回调

    ,但我在哪一点引入这种“并行性”?在某个时刻,程序调用DNSSD.resolve,我认为调用程序需要等到DNSSD解析服务。不,DNSSD.resolve()立即返回,即使解析尚未完成。您的程序可以返回到主循环,处理GUI事件或其他任何事件。解析完成后,处理程序对象将在一个单独的线程中调用,您可以在该线程中对结果执行一些操作,或者将消息排队返回GUI线程以显示结果,等等。您如何看到它是“异步”的?什么使它“异步”?您调用代码并告诉它在工作完成时调用什么函数,而不是同步等待结果。我已经看过这个Java包装器调用的Apple C代码了。你怎么能看到“当解析器工作时,我可以做其他事情”?我认为,如果我调用一个方法,程序将一直加权,直到该方法完成其任务,并且只有在该方法完成任务之后,程序才会执行该方法后给出的代码。请这样想:该方法的任务不是实际解析服务,而只是启动一个线程,稍后可以解析该服务。因此,是的,您的程序必须等待方法完成其任务,但不必等待服务被解析。