2013년 9월 14일 토요일

StarUML - The Open Source UML/MDA Platform

이전 블로그에서 이전 함 (원본 글 2013/09/14 작성)


UML을 지원하는 소프트웨어 모델링 플랫폼으로 버전 1.4에 기반을 두고 있으며 버전 2.0도 지원
UML 프로파일 개념과 템플릿 기반의 문서 및 코드 생성을 지원, MDA(Model Driven Architecture) 접근방법 지원.

유로 UML 모델링 툴이야 좋은 것들이 많지만 무료 중에서는 StarUML이 단연 최고일듯 하다 ArgoUML은 UI interface가 StartUML 보다는 좋지만 안정성이나 기능면에서 좀 못 미더웠음.

하지만 StarUML은 2005년 오픈소스로 전환되고 개발사가 망한 뒤 더이상 개발은 되지 않아 major한 기능 추가는 없는 상태 임.


[특징]
  • 정확한 UML 표준 모델 : OMG 표준 명세에 따라 모델 작성 가능
  • 개방적 소프트웨어 모델 포맷 : 모든 파일 포맷은 XML로 구성, 변환 사용 용이
  • 진정한 MDA 지원 도구 : UML profile을 완벽 지원, Platform Independent Model의 작성 가능
  • 방법론 및 플랫폼의 적응성 : 여러 접근법을 지원(UML, 4+1, StartUML 등)
  • 뛰어난 확장성 : Microsoft COM 자동화를 지원하는 언어에서도 StartUML을 제어하고 통합된 추가 모델 개발 가능
  • 소프트웨어 모델 검증 기능
  • 유용한 Add-In들

[모델링 Documentation]

- Diagram 종류
이어그램 종류설명
 Class Diagram클래스 다이어그램(Class Diagram)은 클래스관련 요소들의 여러 가지 정적인 관계를 시각적으로 표현한 것입니다. 클래스 다이어그램은 클래스(Class) 뿐만 아니라 인터페이스(Interface), 열거형(Enumeration), 패키지(Package) 및 여러 가지 관계들 뿐만 아니라 인스턴스(Instance)와 그것들의 연결(Link) 등도 포함할 수 있습니다.
 Use Case Diagram유스케이스 다이어그램(Use Case Diagram)은 특정 시스템 혹은 개체내의 유스케이스(Use Case)들과 그 외부의 액터(Actor)들 간의 관계를 표현한 것입니다. 유스케이스는 해당 시스템의 기능을 표현하며 그것들이 어떤 외부 액터들과 상호작용하는지를 나타냅니다.
 Sequence Diagram시퀀스 다이어그램(Sequence Diagram)은 인스턴스들이 어떻게 상호작용을 하는지를 묘사합니다. 하나의 협동-인스턴스집합(CollaborationInstanceSet)에 포함된 인스턴스(Instance)들 상호간에 주고받는 자극(Stimulus)들의 집합인 상호작용-인스턴스집합(InteractionInstanceSet)을 직접적으로 표현합니다. 시퀀스 역할 다이어그램(Sequence Role Diagram)은 역할(ClassifierRole) 중심의 관점을 반영한 반면, 시퀀스 다이어그램(Sequence Diagram)은 인스턴스(Instance) 중심의 관점을 반영한 것입니다.
 Sequence Diagram (Role)시퀀스 역할 다이어그램(Sequence Role Diagram)은 역할 개념들이 어떻게 상호작용을 하는지를 묘사합니다. 하나의 협동(Collaboration)에 포함된 역할(ClassifierRole)들 상호간에 주고받는 메시지(Message)들의 집합인 상호작용(Interaction)을 직접적으로 표현합니다. 시퀀스 다이어그램(Sequence Diagram)은 인스턴스(Instance) 중심의 관점을 반영한 반면, 시퀀스 역할 다이어그램(Sequence Role Diagram)은 역할(ClassifierRole) 중심의 관점을 반영한 것입니다.
Collaboration Diagram협동 다이어그램(Collaboration Diagram)은 인스턴스들이 어떻게 협동하는지를 묘사합니다. 하나의 협동-인스턴스집합(CollaborationInstanceSet)에 포함된 인스턴스(Instance)들의 협동 모델을 직접적으로 표현합니다. 협동 역할 다이어그램(Collaboration Role Diagram)은 역할(ClassifierRole) 중심의 관점을 반영한 반면, 협동 다이어그램(Collaboration Diagram)은 인스턴스(Instance) 중심의 관점을 반영한 것입니다.
Collaboration Diagram (Role)협동 역할 다이어그램(Collaboration Role Diagram)은 역할 개념들이 어떻게 협동하는지를 묘사합니다. 하나의 협동(Collaboration)에 포함된 역할(ClassifierRole)들의 협동 모델을 직접적으로 표현합니다. 협동 다이어그램(Collaboration Diagram)은 인스턴스(Instance) 중심의 관점을 반영한 반면, 협동 역할 다이어그램(Collaboration Role Diagram)은 역할(ClassifierRole) 중심의 관점을 반영한 것입니다.
Statechart Diagram상태 다이어그램(Statechart Diagram)은 특정 개체의 동적인 행위를 상태(State)와 그것들간의 전이(Transition)를 통해 묘사합니다. 일반적으로 클래스의 인스턴스에 대한 행위를 묘사하는데 사용되지만 그 밖의 요소들에 대해서도 얼마든지 사용될 수 있습니다.
 Activity Diagram액티비티 다이어그램(Activity Diagram)은 상태 다이어그램의 특별한 형태로써, 활동들의 수행 흐름을 묘사하는데 적합합니다. 일반적으로 작업흐름(Workflow)을 표현하기 위해 많이 사용되며, 클래스, 패키지 혹은 연산 등의 개체에 대해 주로 사용됩니다.
Component Diagram컴포넌트 다이어그램(Component Diagram)은 소프트웨어 컴포넌트 사이의 의존관계를 묘사합니다. 소프트웨어 컴포넌트를 구성하는 요소들과 그것들을 구현하는 요소들도 모두 표현될 수 있습니다.
Deployment Diagram디플로이먼트 다이어그램(Deployment Diagram)은 물리적인 컴퓨터 및 장비 등의 하드웨어 요소들과 그것에 들이 배치되는 소프트웨어 컴포넌트, 프로세스 및 객체들의 형상을 묘사합니다.
Composite Structure Diagram
복합구조 다이어그램(Composite Structure Diagram)은 분류자(Classifier)의 내부 구조를 표현하는 다이어그램입니다. 여기에는 Classifier가 시스템의 다른 부분들과의 상호작용하는 지점 등을 포함합니다.



- Project 생성 시 
  4+1 View Model (Scenarios, Logical View, Development View, Process View, Physical View),
  Default Approach (Use Case Model, Analysis Model, Design Model, Implementation Model, Deployment Model) 등을 선택할 수 있다.
- 물론 각 Model에서 원하는 View를 별도 추가 가능하다. 

Architectural Blueprints—The “4+1” View Model of Software Architecture - Philippe Kruchten


[Screen Shots]


 



2013년 9월 12일 목요일

Android side menu, Navigation Drawer

이전 블로그에서 이전 함 (원본 글 2013/09/12 작성)

 죄송합니다.
본 게시물은 material design이 나오기 전에 작성되어
부분적으로 오래되어 맞지 않는 사항들이 있습니다.
 다른 게시물을 참고하시기를 부탁 드립니다.





App에서 Android side menu, navigation drawer를 사용하고자 찾아 봤고 
side menu를 구현하고자 할 때 참고되는 것들은 아래와 같음.

: 여러 app들에서 사용되고 있다고 함.

: 일반적인 side menu

Navigation Drawer
: Android 공식적으로 제공하는 Navigation Drawer 일반적인 side menu의 기능을 제공함.



일반 사용자들이 만든 library가 주로 사용되고 있는 듯 하지만
그래도 Android에서 제공하는게 있어 호환성, 유지보수성, 귀찮음 측면에서
이를 그냥 사용하기로 함.


일단 아래 링크를 읽어 보면 다음의 사항을을 확인할 수 있다.
 - navigation drawer의 사용이 필요한 경우
 - navigation drawer의 사용 시 navigation flow에 대한 설명
 - navigation drawer와 action bar간의 상호 동작
 - navigation drawer의 구성 시 권고하는 style에 대한 설명
 - 타 side menu library를 사용 시 Navigation drawer로 변경을 위한 checklist

일반적인 side menu를 사용한 app (facebook, 카카오톡 등)을 사용할 경우 일반적으로 이해가 되는 개념이고 꼭 알아둬야 할 것은 ActionBar와의 연동, Style인것 같다.



일단 실제 동작하는 sample 코드와 설명을 보려면 다음 페이지를 확인해야 한다.

navigation drawer의 태양계 행성을 선택하면 화면에 행성의 이미지가 보이는 간단한 샘플이다.
다소 navigation drawer의 동작이 부자연 스럽지만 그냥 간단히 사용하기는 어렵지가 않아 보인다.



해당 링크에서 Navigation Drawer의 사용에 대한 설명을 간략히 정리 하자면


 <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

샘플 코드의 Layout을 보면 DrawerLayout이 전체 view를 차지하는 형태이고
화면에 보여줄 content는 FrameLayout내에서 보여지고 Drawer의 메뉴 항목들은 ListView의 항목으로 추가되어 보여지는 형태이다.

위 링크와 코드에서 강조하는 사항들은 다음과 같다.
- DrawerLayout은 top-level content view로써 layout_width, layout_height의 속성은 "match_parent"이어야 한다.
- main content view인 FrameLayout는 DrawerLayout의 첫번째 child가 되어야 하고 DrawerLayout의 전체 view에서 보여줘야 하므로 mach_parent 속성을 가져야 한다.
- Drawer view의 android:layout_gravity를 right-to-left(RTL)을 지원하기 위해서는 "start"를 선택하라고 하는데.. 사실 뭔소리인지.. 
- Drawer의 사이즈는 height는 parent에 맞게 width는 320dp를 넘지 말게 하라라는 권고.


 private class DrawerItemClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        selectItem(position);
    }
}
/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Create a new fragment and specify the planet to show based on position
    Fragment fragment = new PlanetFragment();
    Bundle args = new Bundle();
    args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
    fragment.setArguments(args);

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
                   .replace(R.id.content_frame, fragment)
                   .commit();

    // Highlight the selected item, update the title, and close the drawer
    mDrawerList.setItemChecked(position, true);
    setTitle(mPlanetTitles[position]);
    mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

샘플에서는 NavigationDrawer의 메뉴를 선택하면 선택된 행성에 대해서 PlanetFragment를 생성하여 content_frame(FrameLayout)에 있는 기존의 fragment와 교체하는 방법으로 구현되어 있음.


 public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...

        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
}

위 Navigation Drawer 예제에서는 Drawer의 open, close 시점에 따라 ActionBar의 메뉴를 조절하는 것을 볼 수 있고 이를 위해서 Android에서 제공하는 ActionBarDrawerToggle을 제공하고 있다.

ActionBarDrawerToggle에 대한 class overview는 다음과 같다.

  This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.
To use ActionBarDrawerToggle, create one in your Activity and call through to the following methods corresponding to your Activity callbacks:
Call syncState() from your Activity's onPostCreate to synchronize the indicator with the state of the linked DrawerLayout afteronRestoreInstanceState has occurred.
ActionBarDrawerToggle can be used directly as a DrawerLayout.DrawerListener, or if you are already providing your own listener, call through to each of the listener methods from your own.

위 class overview에서 강조하는 것 처럼 ActionBar와 NavigationDrawer와 연동 시 status의 동기화(ActionBar 상에서의 indicator를 업데이트 하기 위해) syncState()를 onPostCreate()에서 호출해 주는 것이 중요함.

Clean up the action bar when the drawer is fully expanded. Remove actions that are not needed and display your app's name in the title area.

그리고 참고로 DrawerLayout.DrawerListener는 다음의 methods들로 구성이 되어 있음.

abstract void  onDrawerClosed(View drawerView)
 : Called when a drawer has settled in a completely closed state.
abstract void  onDrawerOpened(View drawerView)
 : Called when a drawer has settled in a completely open state.
abstract void  onDrawerSlide(View drawerView, float slideOffset)
 : Called when a drawer's position changes.
abstract void  onDrawerStateChanged(int newState)
 : Called when the drawer motion state changes.



[관련 링크]

: Stack overflow에서의 Side menu관련 글

: Google IO에서의 Navigation Drawer에 대한 글