Template, Callback
- 클라이언트의 역할은 템플릿 안에서 실행될 로직을 담음 콜백 오브젝트를 만들고, 콜백이 참조할 정보를 제공
- 만들어진 콜백은 클라이언트가 템플릿의 메소드를 호출할 때 파라미터로 전달
- 템플릿은 정해진 작업 흐름을 따라 작업을 진행하다가 내부에서 생성한 참조정보를 가지고 콜백 오브젝트 호출
- 콜백은 클라이언트 메소드에 있는 정보와 템플릿이 제공한 참조정보를 이용해서 작업을 수행하고 그 결과를 다시 템플릿에 돌려줌
- 템플릿은 콜백이 돌려준 정보를 사용해서 작업을 마저 수행
- 경우에 따라 최종 결과를 클라이언트에 다시 돌려주기도 한다.
- 매번 메소드 단위로 사용할 오브젝트를 새롭게 전달 받음
- 콜백 오브젝트가 내부 클래스로서 자신을 생성한 클라이언트 메소드 내의 정보를 직접 참조
- 전략 패턴과 DI의 장점을 익명 내부 플래스 사용 전략과 결합한 독특한 활용법
Calculator.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | public class Calculator { public Integer calcSum(String filepath) throws IOException{ // 콜백 오브젝트 생성 LineCallback<Integer> sumCallback = new LineCallback<Integer>() { // 익명 내부 클래스에서 인퍼페이스 메소드 override public Integer doSomeThingWithLine(String line, Integer value) { return value + Integer.parseInt(line); } }; // 템플릿 메소드 호출 return lineReadTemplate(filepath, sumCallback, 0); } public Integer calcMultiply(String filepath) throws IOException{ // 콜백 오브젝트 생성 LineCallback<Integer> muLineCallback = new LineCallback<Integer>() { // 익명 내부 클래스에서 인퍼페이스 메소드 override public Integer doSomeThingWithLine(String line, Integer value) { return value * Integer.parseInt(line); } }; // 템플릿 메소드 호출 return lineReadTemplate(filepath, muLineCallback, 1); } // 템플릿 메소드(파라미터로 콜백 오브젝트 받음:callback) public <T> T lineReadTemplate(String filepath, LineCallback<T> callback, T initVal) throws IOException{ BufferedReader br = null; try{ br = new BufferedReader(new FileReader(filepath)); T res = initVal; String line = null; while ((line = br.readLine()) != null){ res = callback.doSomeThingWithLine(line, res); } return res; } catch(IOException e){ System.out.println(e.getMessage()); throw e; } finally { if(br != null){ try{ br.close(); } catch (IOException e){ System.out.println(e.getMessage()); } } } } } |
LineCallback Interface
1 2 3 |