아주 예전의 일이다. 프로젝터를 이용해서 회의를 진행할 때였다. 당시, 발표자료 조작을 담당한 분은 나보다는 조금 연배가 위였지만, 한창 실무자인 분이었다. 발표자가 여럿이었기 때문에 그들이 보내오는 짧은 말과 몸짓을 읽어야만 원활한 발표 진행이 가능했다. 그런데 아쉽게도 발표진행은 매끄럽지 못했다. 그 분은 조작도 미숙했고, 다른 사람의 의도를 빨리 파악하지도 못했으면, 업무 내용을 잘 모르고 있어서 발표자가 아주 구체적으로 말해주지 않는 한 오퍼레이팅이 힘들었다. 당시 수십 명이 멍하니 화면 상에 이른바 버벅거리는 마우스와 파일을 잘못 열고, 이곳 저곳 탐색기로 폴더를 돌아다니는 무의미한 영상을 한참 동안 봐야했다. 차라리 내가 하겠다고 나서고 싶은 마음이 굴뚝이었다.

그 후에도 프로젝트를 진행하다 그 분과 비슷한 사람들을 보곤 한다. 솔직히 고하자면, 한 때는 지인들과 함께 그런 부류의 사람들을 비아냥거린 일도 허다하다.

지금에 와서 생각해보면 나도 많은 면에서 일렬로 줄을 세우면 뒤쪽에 쳐져 있을 항목이 많다. 이런 생각이 드는 과정에서 나는 다행히, 역량이 부족하게만 보였던 사람들이 종종 자기 몫을 해내는 분야가 있음을 보아왔다. 그게 프로젝트에 큰 기여를 하는 부분이 아닐 수도 있고, 가시적으로 평가받지 못할 부분일 수도 있지만... '저 사람들은 도대체 무얼 할 수 있을까?'하는 식의 불신의 거만하면서 잔인한 생각을 품었던 내 생각이 조금은 성장할 수 있는 작은 놀라움을 선사하는 순간들이었다.

조급한 마음에 휩싸여 있을 때는 나의 이해와 당장 눈 앞에 놓인 일이 우선한다. 그래서, 그 일을 수행하는 사람들은 뒷전이다. 나의 이해나 내가 바라보는 일에 대한 해석으로 사람을 끼워맞추지만 말고, 먼저 그 사람들을 이해하고 나서 그에 맞는 일을 찾아보면 더 적절한 조합이 보일런지 모른다. 물론, 절대, 절대로 쉬운 일은 아니다. 해볼 만한 시도일 뿐.

작년 여름인가? 청계천 징검다리를 할아버지와 손녀가 손잡고 건너는 모습이 매우 인상 깊었다. 징검다리 건너는 과정을 돕기에는 서로 적절한 조합이 아니었기에 내게는 더욱 뚜렷이 새겨진 모습이다.

이올린에 북마크하기(0) 이올린에 추천하기(0)

오호 좋구만. F9 키 하나로 실행 중인 프로그램 화면을 한번에 볼 수 있다. F11 눌렀을 때, 초고속으로 바탕화면을 볼 수 있는 것도 마음에 든다. 윈도우키 + D 처럼 토글이 아니란 점은 아쉽지만, 버튼 하나만 누르면 되고 더욱 빠른 반응속도는 마음에 쏙 든다. 익스포제 상태에서 w 키로 다는 것도 마음에 든다. 나는 Portable App를 다운 받아 사용했는데, 비스타의 경우 관리자 권한으로 실행해주어야 한다.

익스포제가 무언지 모르시거나 더 자세한 정보를 원하시면: 윈도우에도 맥의 익스포제 효과를~ DExposE2

  • F9 : 모든 윈도우를 화면에 썸네일로 보여주기 (Shift 키를 누르고 하면 슬로우모션)
  • F11 : 모든 윈도우를 최소화하고 데스크탑 화면을 보여줍니다.
  • 탭키 : 익스포제 상태에서 프로그램간의 이동
  • Page Up / Page Down : 익스포제 상태에서 개별 프로그램을 전체화면으로 포커스를 줍니다.
  • w : 익스포제 상태에서 해당 프로그램을 종료시켜 줍니다.
  • 단축키는 아니지만 스크린 특정 위치에 마우스를 위치시키면 익스포제가 실행되는 핫코너 기능도 있습니다.
이올린에 북마크하기(0) 이올린에 추천하기(0)

1. 유용한 단축키
2. 시퀀스 다이어그램 기능

3. 형상관리 제약사항
4. 노트 연결 제약사항
5. UML2 Nesting connector
6. 프레임없는 이미지 복사

유용한 단축키
F3 다이어그램 작성시 연속 선 긋기
Shift + F3 다이어그램 작성시 마지막에 선택한 UML 요소 재 선택
F4 색깔 등의 모양 바꾸기
Ctrl + F4 현재 윈도우 닫기
F12 소스 보기


시퀀스 다이어그램 기능
EA에서 시퀀스 다이어그램을 작성하다가 놀라운 기능을 발견했다.
사용자 삽입 이미지

시퀀스를 작성하다 보면 중첩 호출을 표현할 때 섬세한 마우스질을 요구했다. 그런데, EA에는 activation level을 높였다 내렸다 할 수 있는 버튼이 만들어졌다. 호~

(4/22 22:00 추가)
UML 2.1의 Interaction Use 지원 > Interaction Occurence 요소
스펙에서는 InteractionUse는 상호작용(interaction)에 대한 참조를 의미한다.
EA에서는
Interaction Occurence로 표시한다. 사용법은 기존의 상호작용도(Interaction diagram)를 D&D 하면 된다.

d_InteractionOccurrence

Rose에서는 노트를 만들고, 그 위에 다이어그램을 떨어뜨려서 링크를 만들었는데. 다이어그램에서 중복을 제거하고 가독성을 높이는데 용이하다. 프로그램에서 공통 함수 빼내는 것과 같다.


형상관리 제약사항

Rose 이후의 주류 모델링 도구들이 너무나 불편해서, 90년대 후반에 나온 Rose에 대략은 기능 보강을 한 정도인 EA에 대해서 지나치게 호평만 했다. 특히, EA의 버전 관리 지원은 최상급에서는 RSA의 형상관리 문제에 비교해 훌륭하다고 한 것인데 실전에서는 역시 문제가 발생했다.

XML로 저장하는 일반 모델 파일의 형상관리는 OK이다. 마지막 작업자가 체크인(Check in)을 안하면 다음 작업자가 모델링을 못하는 File-lock 방식에 불평을 하는 팀원도 있었지만, 모델링은 Optimistic lock보다는 File lock(Pessimitic lock) 방식이 좋다. CVS/SVN에 익숙한 개발자가 File lock기반의 VSS가 불편하다고 하는 것처럼,  VSS에 익숙한 개발자들만 있는 곳에서 CVS의 Optimistic lock을 심하게 불평하는 경우도 있다.(CVS를 실제 프로젝트에서는 못쓴다고..ㅡㅡ;)

EA로 형상관리할 때 진짜 문제는 코드와 모델을 싱크한 경우에 발생했다. EA에서는 XML 단위로 모델만 형상관리하지만, 코드 전체가 XML로 저장할 이유는 없다. 확실치 않지만 참조 형태로 연결하는 것 같은데, 이를 CI/CO할 때 시스템 자원을 많이 썼고, SVN에 이를 넣다가 한 PC가 죽어 버리자 Integrity가 깨져서... 스프링 내부 메커니즘 교육용으로 이틀에 걸쳐 수 시간을 쏟은 그림이 사실상 백지로 변했다.

사용자 삽입 이미지

이렇게... 젠장.. 노트만 남았다. 결론, 리버스 하여 코드와 연결시킨 모델의 경우는 윈도우에서 SVN/CVS/VSS 등을 이용해서 형상관리 하거나 형상관리를 끊은 상태에서 백업을 잘 해두자. ㅡㅡ;

코드와 모델을 동기화 하는 것은 대규모 프로젝트에서는 권장할 수 없는 방식이다. 메커니즘 분석을 위해서나 솔루션 개발팀에서 고려할만한 일이다. 보편적인 SI 환경에서는 모델과 코드를 동기화 하는 것이 득보다 실이 많다.

또 하나 EA의 불편함은 CI/CO만 있고, Update를 못한다는 사실이다. 그래서, EA의 명령을 쓰지말고, SVN/CVS/VSS 등의 윈도우 클라이언트로 모델을 관리하는 것이 Best Practices라고 할 수 있다.

노트 연결 제약 사항
사용자 삽입 이미지
노트 링크가 걸리는 UML 요소가 제약이 있어 불편하다. 시퀀스 작성할 때 메시지에 연결이 불가능해 노트와 메시지의 색을 맞춰주거나 하는 방법을 동원해야 한다.

UML2 Nesting connector

선 그릴 때 헷갈리기 쉬운 것이 방향성. UML2에서 포함관계를 표현하는 nesting connector는 포함하는 애가 뭔가(?) 쥐고 있다.

그림 출처: http://www.sparxsystems.com.au/resources/uml2_tutorial/uml2_packagediagram.html

프레임없는 이미지 복사

EA에서 그림 복사하거나 이미지 저장할 때 다이어그램 이름 앞에 cd와 같은 접두어가 붙어 보기 싫었는데... 옵션을 발견했다.

사용자 삽입 이미지

이올린에 북마크하기(0) 이올린에 추천하기(0)

요구사항을 정리하는데 난항이 있다. 고객쪽 수행팀장과 실무자 사이에 견해가 다른 것이다. 실무자 중에서도 수행팀에 속한 TFT 직원과 아닌 사람 사이에도 이견이 있었다. 부서 책임자의 결정으로 미뤄지자 그야말로 사안은 장기 계류(繫留)가 되었다. 복잡한 머리를 식히러 잠시 서점에 들러 본 책에 눈에 띄는 그림이 있었다.

사용자 삽입 이미지
이미지: Managing Agile Projects (Robert C. Martin Series)에서 발췌

안과장은 프로젝트에 당위성을 부여한 부서장과 면담하는 시간을 가질 수 있었다. 부서장의 이야기는 명쾌했다. 그리고, 그는 확고한 비전을 가진 사람이었고, 이 프로젝트는 그의 비전이 그대로 투영된 산물이었다. 신념을 가진 사람과 함께 있으면 동화되기 마련이다. 안과장은 마음으로 고객이기도 그를 최대한 도와야겠다고 마음 먹었다. 부서장 면담이 있고 얼마후 실무자들과 협의를 하는데 자신이 자꾸만 부서장 입장을 변호하는 듯한 위치에 서게 된 느낌이었다. 퍼뜩 놀라 잠시 말을 거두었다.

머릿속으로 부서장 입장에서 시스템이 만들어지고 난 이후를 떠올려보았다. 그리고, 시스템을 실제로 활용할 실무자 입장에도 서봤다. 그리고 시스템의 당위성을 사내에 알릴 테스크포스의 역할까지... 그럴수록 상황이 점점 더 명확해졌다. 몇 주가 지난 지금 안과장은 이해관계자를 유형화 해서 바라보는 것이 상황을 얼마나 명쾌하게 해주는지 알 수 있었다. 사실 그러한 깨달음은 별다른 것도 아니다. 학창 시절 배웠던 포터의 5 forces가 그러하고, 아키텍처를 논할 때 항상 언급하는 4+1뷰도 동일한 원리의 다른 표현일 뿐이다.

Diagram of Porter's 5 Forces
이미지 출처: http://www.usdoj.gov/atr/public/hearings/single_firm/docs/219395.htm

전략적 목표를 가지고 조직의 포석을 결정할 사람의 이해와 당장 업무 편의성이 필요한 실무자의 입장이 다른 것은 자연스러운 일이다. 또한, 책임소재를 가진 사람 즉, 프로젝트를 만드는데 일조한 부서와 책임은 없이 향후 시스템 사용자가 되는 부서의 입장은 확연하게 다르다.

기사 내용과는 무관하게 흥미로운 이해관계자 모델링(표현 방식)

출처: 홈에버가 노동자들을 쥐어짤 수밖에 없는 이유.
이올린에 북마크하기(0) 이올린에 추천하기(0)


3. XML 파싱 단위 테스트를 위한 Mock 생성때 큰웃음(?)을 선사하는 DOMElement
스프링도 사용하는 dom4j에 들어있음.. Thanx

    /**
     * Test do parse element bean definition builder.
     */
    public void testDoParseElementBeanDefinitionBuilder() {
       
        MockControl control = MockClassControl.createControl(BeanDefinitionBuilder.class);
        BeanDefinitionBuilder builder = (BeanDefinitionBuilder) control.getMock();
        MockElement mockElement = new MockElement("service");
       
        control.expectAndDefaultReturn(builder.addConstructorArgValue("value of id"), builder);
        control.expectAndDefaultReturn(builder.addConstructorArgValue("value of name"), builder);
        control.expectAndDefaultReturn(builder.addConstructorArgReference("value of ref"), builder);
        control.expectAndDefaultReturn(builder.addConstructorArgValue("value of description"), builder);
        control.expectAndDefaultReturn(builder.addConstructorArgValue("value of available"), builder);
        control.expectAndDefaultReturn(builder.addConstructorArgValue("value of not-available-message-id"), builder);
        control.replay();
       
        serviceBeanDefinitionParser.doParse(mockElement, builder );
        control.verify();
    }
   
    class MockElement extends DOMElement{

        public MockElement(String name) {
            super(name);
            setAttribute("id", "value of id");
            setAttribute("name", "value of name");
            setAttribute("ref", "value of ref");
            setAttribute("description", "value of description");
            setAttribute("available", "value of available");
            setAttribute("not-available-message-id", "value of not-available-message-id");
        }}

2. JUnit
    public void testAssertEqualsOnDoubleHelper() throws Exception {
        new UnitTests().assertEquals("정확하게 같은 값이 아닙니다.", 0.0000D, 0.0000D);
        new UnitTests().assertEquals("정확하게 같은 값이 아닙니다.", 0.0000D, 0.0000f);
        new UnitTests().assertEquals("정확하게 같은 값이 아닙니다.", 1.0000D, 1.0000f);
       
        try{
            new UnitTests().assertEquals(1.000001D, 1.0000f);
            fail("delta가 존재합니다.");
        }catch (AssertionFailedError e) {
            // junit은 사용자가 지정한 오류 메시지 뒤에 대괄호를 붙이고 그 안에 expected와 actual 값을 문자열로 붙인다.
            assertTrue(e.getMessage().startsWith("완벽하게 동일한 값은 아닙니다."));
        }
    }

1. abstract 클래스 테스트하기
    public void testAutowireMode() throws Exception {
        assertEquals("디폴트 Autowire 모드가  AUTOWIRE_BY_NAME이 아닙니다.", AutowiredIntegrationTests.AUTOWIRE_BY_NAME,
                new MyIntegrationTests().getAutowireMode());
    }
   
    class MyIntegrationTests extends AutowiredIntegrationTests{}


이올린에 북마크하기(0) 이올린에 추천하기(0)

습관적으로 만드는 Top-down 분류 코드를 보고, 거부감이 들었다. 객체지향 초기에 스스로 품고 있었던 악습이 다른 사람의 코드를 통해 재현했기 때문인 듯하다. 깜빡 있고 있었는데, 좋은 그림이 있어서 다시 떠올랐다.