저작권 안내: 저작권자표시 Yes 상업적이용 No 컨텐츠변경 No

스프링5 입문

JSP 2.3

JPA 입문

DDD Start

인프런 객체 지향 입문 강의
2015-11-28일 KSUG에서 발표한 자료 공유합니다.


Posted by 최범균 madvirus

댓글을 달아 주세요

최근에 온라인 쇼핑 시스템을 구축하는 프로젝트를 시작했다. 쇼핑 시스템 자체는 솔루션을 약간 커스터마이징해서 사용할 예정이다. 이 시스템의 사용자는 다음의 요구 사항을 갖고 있다.

  • 현재 사용중인 ERP 시스템에서 쇼핑 시스템의 판매 정보(매출 등)도 함께 보고 싶음
  • 현재 사용중인 ERP 시스템의 재고와 쇼핑 시스템의 재고를 맞추고 싶음
  • 이 ERP 시스템은 외부에서 서비스로 제공
우리가 맡은 책임 중 하나는 쇼핑 시스템과 외부 ERP 시스템 사이의 연동을 처리하는 것이다. 이 프로젝트는 이제 막 시작되었으며 현재는 쇼핑 시스템의 디자인과 요구 사항을 정리하는 과정에 있다. 아직 쇼핑 시스템의 개발자가 본격 투입 전이고, ERP 시스템과의 연계 방식을 논의한 회의를 몇 차례 가졌다.

이 시점에서 우리는 무엇을 할 수 있을까? ERP 시스템과의 연동을 위한 논의만 했을 뿐, 아직 연동을 할 수 있는 시스템은 마련되지 않았다. 또한, 쇼핑 시스템과의 연계 방식은 논의조차 시작하지 못했다. 우리가 만들어야 할 (쇼핑 시스템과 외부 ERP 시스템 간의) 중계 기능의 구현을 시작하기에는 미결정 사항들이 (많이) 존재한다. 게다가 그 결정을 바로 할 수 있는 것도 아니다.

문제는 이 프로젝트의 일정이 녹녹치 않다는 데 있다. 만약 우리가 중계 기능을 제 때에 만들어내지 못하면, 우리 때문에 전체 일정이 밀리게 된다. 그런데, 구현을 위해 필요한 결정을 지금 바로 할 수 없는 처지이다. 그렇다면, 우리는 나중에 뒤에 가서 '그 때 외부 ERP 시스템 개발자와 쇼핑 시스템 개발자가 구현에 필요한 정보를 늦게 알려줘서 어쩔 수 없었다'라고 변경해야 하나? 이런 변명이 통한다면야 좋겠지만, 뒤에 가서 일정을 맞추느라 개!고생을 하게 될 것이다.

고수준 모듈과 저수준 모듈 구별하기

자! 그럼, 우리는 뻔히 보이는 고생을 그대로 받아들여야 하나? 답은 "아니오"이다. ERP 시스템과의 연동 API가 정해지지 않았어도, 아직 쇼핑몰 시스템의 개발자와 미팅을 할 수 없어도, 우리는 중계 기능의 일부를 미리 만들어 낼 수 있다. 우리가 만들 수 있는 영역은 바로 "고수준 모듈"과 관련된 코드이다.

소프트웨어는 고수준 모듈과 저수준 모듈로 구분할 수 있다. 고수준 모듈은 의미 있는 기능을 제공하는 모듈이며, 저수준 모듈은 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현이 된다. 우리가 만들어볼 중계 기능의 일부를 예로 들면 고수준 모듈과 저수준 모듈은 아래와 같이 구분할 수 있다.


여기서, 우리가 저수준 모듈에서 할 수 있는 것이라곤 결과를 보관할 DB 테이블을 정하는 정도이다. 쇼핑 DB에서 데이터를 가져오는 방법도, ERP 서비스 제공 업체에 데이터를 넘기는 방법도 우리가 마음대로 할 수 없다. 하지만, 이런 저수준의 구현 상세함이 정해지지 않았다 하더라도 우리는 고수준의 기능을 구현할 수 있다. 비밀은 바로 DIP에 있다.


DIP를 적용해서 저수준 모듈 없이 고수준 모듈 구현하기


DIP는 Dependency Inversion Principle의 약자로, 이 원칙에 대한 설명은 본 글에서는 생략한다. 이에 대한 내용이 궁금한 독자는 http://en.wikipedia.org/wiki/Dependency_inversion_principle 글 또는 필자가 지은 '객체 지향과 디자인 패턴' 책을 참고하기 바란다.


DIP를 적용해서 저수준 모듈이 고수준 모듈에 의존하게 바꾸면, 저수준 모듈의 상세한 구현 없이도 고수준 모듈을 (어느 정도 수준까지) 만들어낼 수 있다. 아래 그림은 DIP를 적용한 결과를 보여주고 있다.



OrderInfoSync가 의존하는 타입은 모두 인터페이스이므로 Mock을 이용해서 얼마든지 다양한 시나리오의 테스트 코드를 만들 수 있다. 우리는 아래쪽에 붉은 색 상자안에 위치한 저수준 모듈 클래스의 구현이 존재하는지 여부에 상관없이 OrderInfoSync 클래스를 구현할 수 있다.


실제로 지금 이 방식으로 외부 연동을 위한 고수준 모듈의 코드를 한 줄 한 줄 만들어나가고 있다. 물론, 저수준 모듈의 구현없이 고수준 모듈을 완벽하게 구현할 순 없지만, 상당한 양의 구현을 사전에 미리 만들어 낼 수가 있다. 그리고 이 핵심에는 DIP가 있다!



Posted by 최범균 madvirus

댓글을 달아 주세요

안드로이드를 좀 더 잘 해 보기 위해 기초를 다지고 있는데, 그 중 첫 번째로 공부하고 있는 부분이 해상도 및 레이아웃과 관련된 내용이다. 


안드로이드의 주요 단위


안드로이드 기기들이 해상도와 물리적인 크기가 저마다 다르기 때문에, UI 레이아웃을 기기별로 깨지지 않게 만들어주려면 주요 단위에 대한 이해가 필요하다. 다음은 안드로이드 개발시 알아야 하는 용어/단위를 정리한 것이다.


용어 및 단위

설명 

Pixel

화면상의 픽셀 

해상도(Resolution)

픽셀 단위의 화면 크기. 예를 들어, 갤럭시노트 10.1의 해상도는 1280*800인데, 이는 픽셀이 1280개 및 800개임을 의미한다.

DPI (Dots Per Inch) / 밀도

물리적인 1 인치 당 포함되는 픽셀 개수. 예를 들어, 160 DPI는 1인당 픽셀이 160개 포함된다는 것을 의미한다. 주요 DPI는 다음과 같다.

- LDPI (low) : 120 DPI

- MDPI (medium) : 160 DPI

- TVDPI : 213 DPI

- HDPI (high) : 240 DPI

- XHDPI (extra high) : 320 DPI

스크린 크기

물리적인 크기의 종류를 나타낸다. 다음의 4종류가 존재한다.

- X-Large: 주로 10.1 인치 이상의 디바이스

- Large: 주로 5인치 이상의 디바이스

- Normal: 3인치에서 5인치 미만의 사이의 디바이스

- Small: 3인치 미만의 디바이스

 px

픽셀 기반의 단위 

 dip (density-independent pixels) 또는 dp

밀도 독립 단위로, 장치의 밀도에 상관없이 물리적으로 (거의) 동일한 크기를 갖는다. 

 sp (scale-independent pixels)

스케일 독립 픽셀 단위로 , dip와 유사하며, 글꼴 크기를 지정할 때 주로 사용된다.


실제 테스트 해 볼 수 있는 기기별로 확인해보니 주요 값은 다음과 같았다.


 

 갤럭시노트 10.1

옵LTE 2 

넥서스7 

옵Q 

해상도 (픽셀단위)

800 x 1280 

720 x 1280 

800 x 1280 

480 x 800 

해상도 (DP 단위)

800 x 1280 

360 x 640

600 x 961 

320 x 533 

DPI

160 DPI (mdpi)

320 DPI (xhdpi)

213 DPI
(tvdip, hdip) 
240 DPI 

스크린 크기

xlarge 

normal 

large 

normal 

밀도 비율

(DPI / 160)

1.331250

1.5

안드로이드의 기준 DPI는 중간 수준인 160 DPI이다. 160 DPI를 기준으로 DPI가 크면 밀도가 높아지고, DPI가 작으면 밀도가 낮아진다. 또한, 160 DPI인 경우 밀도독립 단위인 DP(DIP)와 픽셀이 같은 크기를 갖는다. 즉, 160 DPI에서 1 DP는 1 PX이 된다.


PX와 DP


옵LTE2와 넥서스7 그리고 갤럭시노트 10.1에서 트위터를 실행해보면, 기기의 크기는 다르지만, 상단 바 부분의  물리적 높이가 동일한 것을 확인할 수 있다. 또한, 글자 크기도 동일한 것을 확인할 수 있다.


[옵티머스LTE2(좌)와 넥서스7(우)에서 트위터를 실행한 화면. 상단 바와 메뉴의 높이가 (거의) 같다]


위 그림에서 두 기기의 높이 해상도는 1280이지만, 물리적인 크기는 넥서스7이 더 크다. 따라서, 위 그림에서 실제 px 단위의 높이 값은 좌측의 옵티머스LTE2가 넥서스7보다 커야 위와 같이 물리적으로 동일한 크기로 표시된다. 모든 기기마다 물리적으로 동일한 높이를 갖는 px 값을 구해서 계산한다는 것은 매우 힘든데, dp 단위를 사용하면 위 그림처럼 기기의 크기에 상관없이 물리적으로 동일한 크기로 레이아웃을 구성할 수 있다.


XML 레이아웃 설정 파일에서 dp 단위로 크기를 지정하면, 안드로이드는 내부적으로 알맞은 px 단위로 값을 변환해서 크기를 구성한다. 따라서, 개발자는 dp 단위를 사용해서 물리적으로 동일한 크기를 갖는 레이아웃을 구성할 수 있다.


코드에서 직접 크기를 설정하는 경우에는 픽셀 단위로 지정하게 되는데, 이 경우 다음의 공식을 이용해서 dp 단위의 값을 px 단위의 값으로 변환할 수 있다.


px = dp * (DPI / 160)


기기의 DPI 구하기


dp 단위의 값으로부터 px 단위의 값을 구하려면 기기의 DPI를 구해야 하는데, 다음의 코드를 이용하면 DPI를 구할 수 있다.


Display dis = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

DisplayMetrics metrics = new DisplayMetrics();

dis.getMetrics(metrics);

// 해상도: dis.getWidth() * dis.getHeight() / metrics.widthPixels * metrics.heightPixels

// DPI: metrics.densityDpi

// 밀도비율 (DPI / 160) : metrics.density


참고자료

  • 기기별 DPI/해상도/크기 등: http://developer.android.com/tools/revisions/platforms.html
  • Supporting Multiple Screens: http://developer.android.com/guide/practices/screens_support.html


Posted by 최범균 madvirus

댓글을 달아 주세요