首页 > 代码库 > Java回调:补充资料

Java回调:补充资料

在什么是好莱坞原则中,yqj2065大话连篇,木有代码。这里补充一点代码。

1.回调以通知取代轮询

在分层架构中,上层模块Client调用了下层模块Server的copy()方法,上层并不清楚复制的进度而只有下层的Server才知道。上层获得进度数据的方式:轮询和通知。通知的代码见回调与Java8的λ表达式。

轮询。下层模块Server0将进度数据保存在一个成员变量x中,并提供getX()。Client通过轮询访问该数据。

轮询方式下,一个线程中Server0努力的复制,主线程则在while(true)中随时随地的查询数据,直到复制进度数据为100才结束。

package principle.callback.sub;
public class Server0{
    private int x;//复制工作的进度
    public int getX(){ return x;    }
    public void copy() {
        while(x<100){
            try{
                Thread.sleep(10);
                x++;
            }catch(InterruptedException e){}
        } 
    }
}

package principle.callback;
import principle.callback.sub.Server0;
public class Client0{
    private Server0 server =new Server0();
    public void call() {  server.copy();  }
    
    public static void test() throws InterruptedException{
        Client0 c =new Client0();
        Runnable r = ()->c.call();
        new Thread(r).start(); 
        System.out.print("进度:");
        int x2 = 0;
        while(true){
            int x1 = c.server.getX();///10
            Thread.sleep((int)(Math.random()*100));
            if(x2 >=100){
                System.out.println();
                break;
            }
            if (x2 != x1) {                
                System.out.print(x1+"% ");
                x2 = x1;
            }
        }
    }  
}

下面是两次测试的结果。

进度:3% 5% 9% 16% 21%23% 29% 31% 38% 48% 57% 63% 70% 76% 82% 85% 87% 88% 90% 91% 97% 100%

进度:1% 6% 12% 16% 24%31% 39% 47% 49% 54% 61% 64% 67% 77% 83% 90% 100%

轮询方式的优点:上层模块能够随时随地的了解所需的数据(不会被下级欺瞒),依赖关系和方法调用关系都很明确;下层模块代码简洁。缺点:上级时刻盯着下级干活,比较讨嫌;获得数据时执行太多的调用(特别是在网络编程如远程方法调用时,这是不能够容忍的);

2. 回调与多态

讨论回调、好莱坞原则时,都强调了其应用场景:分层架构。那么在非分层架构中,这些思路和技术难道不可以使用吗?如果能够使用,回调、好莱坞原则的概念是否应该推广到更一般的场合——普通类之间的设计?

答案是:在同层中,程序员依然可以使用该技术,它也是解决类之间相互依赖的重要手段。之所以强调其应用场景是分层架构,因为分层强制性地要求依赖的单调性,因而不得不使用回调、好莱坞原则达到反向调用的目标。程序员不得不在下层(或基础设施/框架中)定义一个Client的父类型IClient,它定义了回调callback(int)的接口。

如果不能够强制性地要求依赖的单调性,那么同一层中,回调与通常的多态,从类图和其自身代码上,没有区别。


当然,如果同一层中出现图0-5所示的循环依赖,程序员“可以”(而不是“不得不”) 定义一个B的父类型IB,这样就可以将A与B的循环依赖修改为单向依赖;然而对以程序员而言,是否修改为单向依赖是可选的。

另一方面,同一层中,回调、好莱坞原则的概念可以使用观察者模式作为代称。换言之,虽然观察者模式可以作为回调、好莱坞原则的同义词。但是,回调、好莱坞原则用于分层架构,观察者模式用于同一层中类的关系描述。



Java回调:补充资料