差異處
這裏顯示兩個版本的差異處。
下次修改 | 前次修改 | ||
java:java8:functionalinterface:method_reference [2017/02/24 13:59] tony 建立 |
java:java8:functionalinterface:method_reference [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 2: | 行 2: | ||
====== Method Reference ====== | ====== Method Reference ====== | ||
===== Problem ===== | ===== Problem ===== | ||
- | 我有個透過JNA去存取硬體資料的程式, | + | 我有個透過JNA去存取硬體資料的程式: |
<code java> | <code java> | ||
public interface Bus extends Library { | public interface Bus extends Library { | ||
行 46: | 行 46: | ||
問題是: 如果我有10個bus相關操作,不就要寫很多一樣的code嗎? | 問題是: 如果我有10個bus相關操作,不就要寫很多一樣的code嗎? | ||
===== How to resolve? ===== | ===== How to resolve? ===== | ||
+ | 一開始我就想,除了aop、intercepter等方式外,function pointer應該就能解決我的問題: 只要有一個method會在critical action前後做lock與release就可以了。類似以下: | ||
+ | <code java> | ||
+ | void busAction(Function* criticalAction){ | ||
+ | lockAndWait(); | ||
+ | |||
+ | criticalAction->invoke(); | ||
+ | |||
+ | release(); | ||
+ | } | ||
+ | </code> | ||
+ | 最後宣告一個名為BusAction的FunctionalInterface: | ||
+ | <code java> | ||
+ | @FunctionalInterface | ||
+ | public 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。 | ||
+ | ===== 後記 ===== | ||
+ | 如果不想額外增加Interface,也可以直接使用Runable或Callable,取決於你是否要讓語義更清楚而已。 | ||
===== Reference ===== | ===== Reference ===== | ||
* [[https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html|Oracle Java - Method 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]] | * [[http://stackoverflow.com/questions/34888904/function-pointers-as-parameters-in-java-8|function-pointers-as-parameters-in-java-8]] | ||
+ | * [[http://blog.dontcareabout.us/2013/03/functional-interfacejava-8.html|functional interface:Java 8 重新製作的概念]] | ||
+ | ===== ===== | ||
+ | ---- | ||
+ | \\ | ||
+ | ~~DISQUS~~ |