Framework/Another Lore2009. 6. 25. 10:47

습관은 관습을 낳고 관습은 편견을 낳는다. 

우리는 bean 객체를 많이 봐왔기 때문에 getMethod가 있으면 setMethod도 있어야 할 것이라고 생각한다. 물론 이것이 틀렸다고는 할수 없지만 가끔은 생각을 바꿔보는게 도움이 될 수 있다. 

예컨데 다음 상황을 보자. 

Node rootNode = session.getRootNode() ;
NodeType empType = getNodeType("employee") ;

Node newNode = rootNode.createChild(empType, "abcd") ;


이 상태에서 newNode를 repository에 저장하는게 좋을까? 아니다. 그러기엔 너무 일러보인다. 왜냐하면 아직 실제 값을 설정하지 않았기 때문이다. 

그 보다는 
newNode.setProperty("ename", "bleujin") ;
newNode.setProperty("empNo", 20) ;
와 같이 값을 설정하고 

newNode.save() 를 호출했을때 repository에 저장하는게 보다 효율적일 것이다. Transaction Handling이 가능하고 setProperty를 호출할때마다 DBCall을 하는것보단 훨씬 효율적이다. 


다만 위의 경우 문제가 있다. 

다음 상황을 상상해 보자. 

Node parent = rootNode.createChild(empType, "parent") ;
Node child = parent.createChild(empType, "bleujin") ;
child.setProperty("ename", "bleujin") ;
child.setProperty("empNo", 20) ;
child.save() ;

별문제가 없어보인다. 
그러나 위와 같이 현재 Session의 모든 PendingEvent를 저장하는 session.save() 를 호출하지 않고 child.save() ;를 호출했을 경우에 (물론 API 상으로는 아무런 문제가 없다.) parent가 저장되지 않은 상태에서 child가 먼저 저장될 수 있는가? 에 대한 의문이 든다. 더군다다 child만 save()하고 parent는 일부러 혹은 실수로 save를 하지 않거나 혹은 parent.save()를 호출했을 경우에 에러가 발생했을 경우를 상정해 보면 문제가 더욱 복잡해진다. 

API상으로는 문제가 없지만 child만 save가 되고 parent는 save 되지 않았을 경우는 정상적인 상태가 아니다. 그렇다고 맨 처음의 방식으로 돌아가는 것도 Transaction이 보장되는 것은 아니다. 각각의 호출마다 repository Call을 했을 경우 첫번째와 두번째 사이에 에러가 발생할 수 있다는 것은 마찬가지 이다. 

물론 사용자 실수야 라고 탓이라고 문제를 회피할 수도 있겠지만 이는 올바른 방법이 아니다. 순서에 의존하는 API는 (예컨데 a를 호출하고 난 다음에 b를 호출하고 그 다음에 c를 호출하고..) 사용하기 복잡하고 실수를 가져오는게 당연하다. 

이 문제를 해결하기 위해 AL은 존재와 무존재를 구분한다. 
예컨데 


interface INode {
    .......
    getterMethod() ;
    setterMethod() ;
    Node retrieve(...) ;
    Node save() ;
}

interface NodeTemplate extends INode {
     ....
}

interface Node extends INode {
    NodeTempalte createChild(NodeType nodeType, String name) ;
}

와 같이 인터페이스를 분리하면 문제는 명확해진다. 
ISP(Interface Segregation Principle)의 의미는 어렵지 않지만 책임의 한정이 어렵다. 여기서는 책임을 read책임과 write책임으로 분리한 것이다. 


NodeTemplate parent = rootNode.createChild(empType, "parent") ;
위 상태에서 NodeTemplate는 createChild Method를 호출할 수 없기때문에 

Node savedParent = parent.save() ; 를 호출한 이후 child를 만들거나 아니면 session.save()를 호출하여 pendingEvent를 같이 처리해야 한다. 


위 예제에서 좀더 나아가서 getMothod용 Node와 setMethod용 Node를 구분한다면 개선의 소지가 더 있다. 이를테면 Setter가 없는 Node를 통해 더 가벼운 Node를 만들 수 있게 된다. 그리고 Getter가 필요없는 Node를 통해 더 빨리 Node를 얻어올 수 있다. 




'Framework > Another Lore' 카테고리의 다른 글

XUL 단상  (0) 2009.07.15
레이어의 속도  (0) 2009.07.05
최근에 책을 읽다가..  (0) 2009.06.11
AL : Permission  (1) 2009.04.30
AL : 현재의 난제들  (0) 2009.04.30
Posted by bleujin