JUnit로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

JUnit로 검색한 결과
등록일:2009-01-13 19:29:36
작성자:
제목:이클립스 EMF와 GEF를 이용한 개발지침서(공개문서)


개요

이 문서에서는 EMF와 GEF를 이용하여 모델기간의 그래피컬 에디터를 만들때 고려해야 하는 방법들과 Know-How를 소개한다. 개발자는 여기에 언급된 내용을 충실히 이행할 때 좀더 효과적이고 생산성높은 프로그래밍을 할 수 있다.

알아둘 것

이 글에서 알아둘 몇가지 용어들을 먼저 정의할 필요가 있다.
  • EMF는 Eclipse Modeling Framework의 이니셜로, Eclipse에서의 모델을 통합하기 위해 Ecore 라는 Meta-Meta-모델 이다. 이것은 Meta 모델의 상위 개념인데, Meta 모델은 보통 UML 과 같이 어떤 구조를 표현하기 위해 사용하는 명세모델이다. 따라서 Meta-Meta-모델은 Meta-모델을 명세하기 위해서 사용된다. EMF는 Meta-모델인 XML Scheme 나 UML 모델을 Ecore 형태로 표현한다.
  • GEF는 Graphical Editing Framework 의 이니셜로, SWT를 이용하여 Draw2D 래퍼 클래스를 제공한다. GEF의 구조는 MVC패턴을 사용하여, 모델과 뷰어 사이의 종속성을 없애고 콘트롤러와 사용자와 상호작용이 가능하게 하는 형태의 프레임웤이다.
  • 일반적으로 XML Scheme와 XML 데이터를 구별하는데, XML Scheme는 XML의 구조의 서술하는 Meta-Model이다. 즉, XML Scheme에서 서술한 형태의 모든 원소들을 XML데이터라고 한다. 집합을 정의할 때도 이렇게 할 수 있는데, "집합 A는 1보다 크고 10보다 작은 자연수의 집합이다" 라는 문장은 Scheme가 되는 것이고, 여기에 포함된 원소인 1,2,3,4,5,6,7,8,9,10 은 데이터가 되는 것이다.
  • EMF는 모델로 부터 모델을 운영(Driven)할 수 있는 소스코드를 생성해 주는데 이 코드를 모델코드라고 부르겠다.
  • 클래스와 오브젝트는 다르다는 것은 이미 알 것이라 생각한다. 오브젝트는 인스턴스라고 부르는 경우도 있는데, 여기서 오브젝트는 메모리에 있는 속성과 메소드들이 묶음이라고 정의하고 인스턴스를 그 오브젝트를 가르키는 레퍼런스라고 하겠다.

그리고 이 문서를 정확히 이해하기 위해서는 먼저 EMF에서 모델을 자연스럽게 생성하고, GEF에서 팔렛트를 설정하거나 Editpolicy를 Install 하는것이 낮설지 않다고 생각되어야 한다.

EMF와 GEF를 이용한 개발 지침

  1. EMF에서 모델을 만들고 소스코드를 생성하면 모델과 관련된 메소드가 포함되어 있는 4가지 프로젝트가 생성된다. 이것은 (모델이름), (모델이름.edit), (모델이름.editor), (모델이름.tests) 프로젝트 인데 여기서 edit와 editor, tests는 (모델이름) 프로젝트와 종속성이 있으므로, (모델이름)의 모델이 바뀌면 다른 것들은 다시 생성해 주어야 한다. 제일 처음 모델 코드가 생성되면 가장 먼저 각 모델의 instance를 조직해 보아야 한다. 이때는 제공된 프로젝트인 tests 에서 JUnit 테스트를 바로 해보는 것이 적당한다. 또한 모델의 성공적인 저장과 불러오기를 위해서 (모델이름Example.java) 를 tests 프로젝트에서 찾아서 실행시켜 보는 것이 좋다.

    이런것들은 추후에 자신이 작성한 코드에 이상이 있는지 자동으로 생성된 모델 코드에 이상이 있는지를 즉각 알 수 있도록 해준다.

  2. EMF가 생성해준 모델코드를 너무 신뢰하지 말라!

    EMF에서 모델코드를 생성하기 위해서는 JET 엔진을 사용하는데, 대부분의 Acessor메소드(set/get) 은 잘 생성되는데, 구조적인 부분인 List나 Tree 형태의 모델들은 엉망인 경우가 있다. 또한 지나치게 인터페이스(Interface)와 구현(Implementation)을 분리해 놓아서 실제로 생성된 모델코드로 구현하는데에는 복잡함 이라는 문제가 있다. 이럴 때는 수동으로 모델 생성코드를 조정해 주어야 하는데 클래스에서 공통된 부분을 추출하여 super 클래스를 만드는 것은 다른 프로젝트의 코드와의 호환 문제로 어려울 수 있다. 따라서 기존의 생성된 모델은 그냥 두고, 여러가지를 통합한 인터페이스를 생성하는 것을 권장한다. 예를 들어 두개의 모델 코드를 보도록 하자!
    //IRectangle.java
    public interface IRectangle{
      void setWidth(int w);
      void setHeight(int w);
      int getWidth();
      int getHeight();
      // different
      void setScale(float scale);
      float setScale();
    }
    
    IBox.java
    public interface IBox{
      void setWidth(int w);
      void setHeight(int w);
      int getWidth();
      int getHeight();
      // different  
      void setBound(int bounds);
      int getBound();
    }
    
    
    와 같이 생성되는 인터페이스가 있는지 확인하고, 이것들을 위해서 다음과 같은 인터페이스를 생성한다.
    ISize.java
    public interface ISize{
      void setWidth(int w);
      void setHeight(int w);
      int getWidth();
      int getHeight();
    }
    
    그리고 이 인터페이스를 기존의 구현 클래스에 다음과 같이 적용한다.
    //RectangleImpl.java
    public class RectangleImpl implements IRectangle, ISize{ 
    ....
    }
    //BoxImpl.java
    public class BoxImpl implements IBox, ISize{ 
    ....
    }
    
    이렇게 하면 Box와 Rectangle 모델을 운영할 때 getWidth와 getHeigt를 사용하기 위해 EObject를 instanceof 해서 어떤 모델인지 구별할 필요없이 바로 ISize로 서브타이핑하여 사용할 수 있다.

  3. GEF에서의 Command는 최대한 작은 형태로 여러개를 만든다.

    Command는 execute 메소드 하나당 하나의 모델 데이터를 수정하도록 하는 것이 좋다. 물론 이렇게 너무 작게 쪼개면 Editpolicy 에서의 조건 분기가 거슬리긴 하지만, 이것보다 하나의 Command에 많은 모델 변경이 일어나서 Notify가 엉망으로 일어나는 것을 미연에 방지할 수 있다. 한번에 여러가지 Command를 실행해야 하는 경우에는 TransactionCommand를 만들어서 여기에 모델이 수정되는 작은 Command를 List형태로 전달하여, TransactionCommand가 execute될때 전달받는 Command들을 실행 하는것이 좋다.
    //TransactionCommand.java
    public class TransactionCommand extends Command{
    
      private ArrayList<Command> command_list = new ArrayList<Command>
      void setCommand(Command){
        command_list.add(Command);
      }
      void execute(){
        Iterator<Command> iter = command_list.iterator;
        while(iter.hasNext()){
          Command cmd = iter.next();
          if(cmd.canExecute()){
            cmd.execute();    
          }
          else{
            return;
          }
        }  
      }
    }
    


  4. Notify를 수동으로 일어나게 할 때에는 반드시 Editpart와의 종속성을 없애라!

    GEF에서 Notify는 아주 중요한 속성중에 하나이다. 작성되는 거의 대부분의 Editpart는 모델의 상태를 감지하기 위해서 editpart 스스로가 Activate() 메소드가 호출 될때 옵저버로 등록이 되도록 프로그램을 작성하게 된다. EMF의 Notify는 set메소드나 List.add 메소드가 호출 될때 발생하는데 Editpart가 refresh 될 때 Notify를 강제로 발생하면 이 Notify는 다시 Editpart로 전달되고 전달된 Notify를 받고 다시 refresh 하고 또 Notify를 보내고 하는 순환구조가 생겨버리게 된다. 따라서 Notify를 수동으로 보내야 되는 경우에는 Editpart와 모델과의 종속성이 없는 곳에서 대리자를 만들어서 제공해야 하며, 모델을 관리하는 ModelManager를 만들어서 modelRefresh() 메소드를 추가하는 것이 좋다.

  5. 팔렛트를 사용한 편집과 Action을 사용한 편집을 프로그램이 작성되기 전에 고려하라!

    GEF에서는 팔렛트를 편집이 일어나는 시작점으로 제공한다. 그러나 이 팔렛트는 GEF에서 완전히 커스터마이즈 할 수 있는 방법을 제공하지 않고 있기 때문에, 때에 따라선 편집방법을 구현하기 위해서는 Tool Entry를 새롭게 디자인 한다거나 Action을 만들어야 하는 경우가 있다. 처음에 팔렛트를 사용하여 편집할 수 있는 방법과 Action을 이용하여 편집하는 방법을 미리 정해 놓으면 나중에 힘들게 Tool Entry를 만들려는 노력을 줄일 수 있다.