개발

UML 찍먹해보자 그런데 이제 자바를 곁들인

brobro332 2024. 11. 4. 20:46
반응형

왜 알아야 해?

최근 자바 디자인 패턴과 리팩토링 관련 책을 읽었다. 두 책 모두 UML을 통해서 개념을 설명해 주었다.

물론 친절하게도 책의 첫 장에서 UML 기초적인 부분을 다뤄서 책을 읽는 데는 문제가 없었지만, 나중에 프로젝트 진행할 때도 요긴하게 써먹을 수 있을 것 같아서 정리해 놓으려고 한다.

 

그래서 그게 뭔데?

  • Unified Modeling Language의 약어로, 시스템을 시각화하고 문서화하기 위한 표현 방법이다.

 

클래스 다이어그램

interface Executable {
    abstract void execute();
}

abstract class ParentClass {
    something _field1;
    static int FIELD2;
    
    abstract void method1();
    void method2() {
        	// ...
    }
    
    static void method3() {
        	// ... 
    }
}

class ChildClass extends ParentClass implements  Excutable {
    void method1() {
        // ...
    }
    
    void excute() {
        // ...
    }
}

class Something {
    int _value;
    // ...
}
상기 코드를 다이어그램으로 만들면 어떻게 될까?

 

  • 클래스 다이어그램은 클래스, 인스턴스, 인터페이스의 정적 관계를 표현한다.
  • 실제로 클래스만 등장하지는 않는다.

 

클래스와 계층 관계

  • 화살표를 가리키려면 상대를 알고 있어야 한다.
  • 그렇기 때문에 화살표는 하위 클래스에서 상위 클래스로 향한다.
  • 상위 클래스는 하위 클래스를 몰라도 되지만, 하위 클래스는 상위 클래스를 알아야 한다.
  • 이걸 의존한다고도 표현할 수 있다.

어떻게 작성할까?

  • 클래스 다이어그램 작성에는 다음과 같이 몇 가지 규칙이 있다.
  1. 각각의 클래스는 직사각형으로 표현한다.
  2. 직사각형을 수평선으로 나눠 클래스명, 필드명, 메소드명을 순서대로 적는다.
  3. 액세스 제어 또는 메소드의 인자 등 부가정보를 적거나 생략해도 된다.
  4. 추상(abstract) 클래스와 필드는 기울임 꼴로 작성한다.
  5. 정적(static) 클래스와 필드는 밑줄을 긋는다.
  • 생략이 존재하므로 당연히 클래스 다이어그램으로부터 소스 코드를 복원할 수는 없다.

인터페이스와 구현

interface Printable {
    abstract void print();
    abstract void newPage();
}

class PrintClass implements Printable {
    void print() {
    	// ...
    }
    
    void newPage() {
    	// ...
    }
}
  • <<interface>>를 명시하여 인터페이스를 표현한다.
  • 화살표는 당연하게도 구현체가 인터페이스를 가리킨다.

 

집약

class Color {
    // ...
}

class Fruit {
    Color color;
}

class Basket {
    Fruit[] fruits;
    // ... 
}
  • 가령 바구니에 여러 개의 과일이 있고, 당연하게도 과일에는 색깔이 있다.
  • 각각을 인스턴스와 필드 개념으로 보고 클래스 다이어그램으로 표현하면 다음과 같다.

 

  • 앞서 설명했듯 인스턴스를 필드로 갖고 있는 형태를 집약이라고 한다.

 

액세스 제어

class Something {
    private int privateField;
    protected int protectedField;
    public int publicField;
    int packageField;
    
    private void privateMethod() {
    
    }
    protected void protectedMethod() {
  
    }
    public void publicMethod() {
   
    }
    void packageMethod() {
   
    }
}
  • 요건 클래스 다이어그램은 생략한다.
  • public은 +를, private는 -를, protected는 #을 클래스 앞에 명시한다.
  • 같은 패키지 내의 클래스만 액세스 하게 하려면 ~를 클래스 앞에 명시한다.

 

관계

  • 클래스 간 관계를 나타내기 위해 화살표에 ▶ 마크와 설명을 함께 기재할 수 있다.
  • 가령 사용하거나 생성하는 등의 관계가 존재할 수 있다.

 

시퀀스 다이어그램

  • 프로그램이 작동할 때 어떤 메소드가 어떤 순서로 실행되는지 표현한다.
  • 클래스 다이어그램은 시간이 지나더라도 변함이 없는 정적인 관계를 표현하는 반면 시퀀스 다이어그램은 시간에 따라 변함이 존재하는 동적인 관계를 나타낸다.
  • 시퀀스 다이어그램은 다음과 같이 작성한다.
  1. 각 인스턴스는 다이어그램 위쪽에 직사각형으로 표현한다.
  2. 직사각형 안에는 콜론 : 뒤에 클래스 이름을 쓰고 밑줄을 긋는다.
  3. 인스턴스에 이름이 필요할 때는 servername:Server처럼 콜론 앞에 이름을 적는다.

 

  • 각 인스턴스에서 아래 방향으로 뻗은 파선을 라이프 라인이라고 한다.
    • 생명선이라고도 하는데, 시간이 아래 방향이 흐른다고 생각하면 된다.
    • 라이프 라인은 인스턴스가 생존하는 동안만 존재한다.
    • 라이프 라인 중간의 세로로 긴 직사각형은 객체가 활동 중임을 나타낸다.

 

  • 실선으로 된 검은색 화살표는 메소드 호출을 나타낸다.
    • 가령 open 라벨이 붙은 화살표를 보면 client가 server의 open 메소드를 호출했음을 알 수 있다.

 

  • 메소드 호출에서 시작하여 직사각형의 아래에서 왼쪽으로 뻗는 실선의 화살표는 메소드의 반환을 나타낸다.
    • 반환 값이 없을 경우 생략할 수 있으며, 반환되면 해당 인스턴스의 생존은 종료된다.

 

  • 이처럼 라이프 라인을 따라 위에서부터 차례대로 읽어 나가고, 화살표를 따라가서 인스턴스 간의 협조 동작을 확인한다.

 

마치며

  • 모델링은 중요하다.
  • 모델링이 제대로 안 되면 수정을 반복하게 되고, 테스트도 그만큼 잦아진다.

 

나는 무언가를 진행할 때 머릿속으로 계획하는 편인데 개발자로서 정말 안 좋은 버릇이다. 😨

 

이미지 출처

 

통합 모델링 언어 - 위키백과, 우리 모두의 백과사전

통합 모델링 언어(UML, 영어: Unified Modeling Language)는 소프트웨어 공학에서 사용되는 표준화된 범용 모델링 언어이다.[1] 이 표준은 UML을 고안한 객체 관리 그룹에서 관리 하고 있다. UML 다이어그램

ko.m.wikipedia.org