差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

java:java8:functionalinterface:method_reference [2017/02/24 14:31]
tony [How to resolve?]
java:java8:functionalinterface:method_reference [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​java lambda}} 
-====== Method Reference ====== 
-===== Problem ===== 
-我有個透過JNA去存取硬體資料的程式:​ 
-<code java> 
-public interface Bus extends Library { 
- Bus INSTANCE = (Bus) Native.loadLibrary( "​buslib",​ Bus.class); 
-  
- boolean sendData(byte bus, byte data[]); 
- boolean getData(byte bus, byte data[]); 
-} 
-  
-public boolean sendData(byte bus, byte data[]){ 
- synchronized (Bus.class) { 
- return Bus.INSTANCE.sendData(bus,​ data); 
- } 
-} 
  
-public boolean getData(byte bus, byte data[]){ 
- synchronized (Bus.class) { 
- return Bus.INSTANCE.getData(bus,​ data); 
- } 
-} 
-</​code>​ 
-某天有了需要做存取控管需求,因此我在Bus Library介面上增加了兩個methods:​ 
-<code java> 
-boolean lockBus(byte bus); 
-boolean releaseBus(byte bus); 
-</​code>​ 
-而sendData中,在實際請求前會先lockBus,使用後再releaseBus:​ 
-<code java> 
-public boolean sendData(byte bus, byte data[]){ 
- synchronized (Bus.class) { 
- try { 
- boolean ret = false; 
- if (!(ret = Bus.INSTANCE.lockBus(bus))) { 
- return ret; 
- } 
- return Bus.INSTANCE.sendData(bus,​ data); 
- } finally { 
- Bus.INSTANCE.releaseBus(bus);​ 
- } 
- } 
-} 
-</​code>​ 
-問題是: 如果我有10個bus相關操作,不就要寫很多一樣的code嗎? ​ 
-===== How to resolve? ===== 
-一開始我就想,除了aop、intercepter等方式外,function pointer應該就能解決我的問題:​ 只要有一個method會在critical action前後做lock與release就可以了。最後使用了Java8的FunctionalInterface,宣告以下介面:​ 
-<code java> 
-@FunctionalInterface 
-private interface BusAction { 
- boolean invoke(); 
-} 
-</​code>​ 
-而我處理lock與release的method如下:​ 
-<code java> 
-private boolean invokeBusAction(byte bus, BusAction action){ 
- synchronized (Bus.class) { 
- try { 
- boolean ret = false; 
- if (!(ret = Bus.INSTANCE.lockBus(bus))) { 
- return ret; 
- }  
- return action.invoke();​ 
- } finally { 
- Bus.INSTANCE.releaseBus(bus);​ 
- } 
- } 
-} 
-</​code>​ 
-最後就是sendData與getData:​ 
-<code java> 
-public boolean sendData(byte bus, byte data[]){ 
- return invokeBusAction(bus,​ ()->{ 
- return Bus.INSTANCE.sendData(bus,​ data); 
- }); 
-} 
-  
-public boolean getData(byte bus, byte data[]){ 
- return invokeBusAction(bus,​ ()->{ 
- return Bus.INSTANCE.getData(bus,​ data); 
- }); 
-} 
-</​code>​ 
-透過以上方法,可以讓我大幅減少duplicated code。 
-===== Reference ===== 
-  * [[https://​docs.oracle.com/​javase/​tutorial/​java/​javaOO/​methodreferences.html|Oracle Java - Method Reference]] 
-  * [[http://​stackoverflow.com/​questions/​34888904/​function-pointers-as-parameters-in-java-8|function-pointers-as-parameters-in-java-8]] 
- 
- 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~