Context Reuse : Pass the executable code as Parameter to methods : JAVA 8
Context Reuse
Context reuse is a special kind of code reusability. Context reuse is the reuse of Set of Instructions while various different actions take place in between.
Following are the steps to understand context reuse:
- Before Block ( Fixed set of Instruction)
- Your action or code you want to execute
- After Block (fixed set of instruction)
Consider the Scenario:
Two different methods want to use inputStream :
- Method 1: write the InputStream to stdout
- Method 2: read the input stream to String and return the Object.
See the implementation
public void printStream(InputStream inputStream) throws IOException { if(inputStream == null) return; IOException exception = null; try{ int character = inputStream.read(); while(character != -1){ System.out.print((char) character); character = inputStream.read(); } } finally { try{ inputStream.close(); } catch (IOException e){ if(exception == null) throw e; } } } public String readStream(InputStream inputStream) throws IOException { StringBuffer buffer = new StringBuffer(); if(inputStream == null) return; IOException exception = null; try{ int character = inputStream.read(); while(character != -1){ buffer.append((char) character); character = inputStream.read(); } return buffer.toString(); } finally { try{ inputStream.close(); } catch (IOException e){ if(exception == null) throw e; } } }
the action around the stream is different but the context around these actions is the same :
Now you can map
Now you can map
- opening of the stream (Before Block)
- Special Action (You want to execute)
- Closing of the stream (After Block)
Java 8 provides Function Interface so that you can use the context reuse
private interface IProcessStreamFunction{ // function interface R processStream(InputStream inputStream); } // context reuse action is passed as parameter using IprocessStreamFunction private T processStream(File demoFile,IProcessStreamFunction processFunction) { try (FileInputStream fileInputStream = new FileInputStream(demoFile)) { return processFunction.processStream(fileInputStream); } catch (IOException e) { e.printStackTrace(); return null; } } public void readStream() { String fileName = "path-to-readStreamFile"; processStream(new File(fileName), inputStream -> { return readInputstream(inputStream); // reading the stream }); } public void writeStream() { String fileName = "path-to-writeStreamFile"; processStream(new File(fileName), inputStream -> { return writeInputStream(inputStream); // writing the stream }); }
procesStream code needs not to be changed and It can be reused when you need to with reading of the file.
Uses
Context reuse is quite powerful and can be used in many other contexts than stream processing. An obvious use case is the correct handling of database connections and transactions (open - process - commit()/rollback() - close()). Other use cases are NIO channel processing, and thread synchronization in critical sections (lock() - access shared resource - unlock()). It could also just be something as simple as turning checked exceptions of an API into unchecked exceptions
Comments
Post a Comment