2014년 7월 8일 화요일

Material Design 단상

개인적으로는 언제부터인가 몇 번이나 말해온 내용을 좀 더 공식적이고 권위있는 목소리로 말해줘서 무척이나 감격스럽다.


나는 이 영상을 계기로 ux에 대해서 '직관성', '직관적인' 등의 단어가 무분별하게 남용되지 않기를 바란다. 이 영상은 애플의 스큐어몰피즘이 어째서 작동하는 매커니즘인지를 그런 모호한  단어들보다 훨씬 잘 설명한다.


영상의 최초의 키워드는 메타포(은유)이다. 메타포는 서로 공유하는 경험, 짧은 스토리를 통한 강력하게 함축된 전달이다.

안드로이드의 Material Design이 택한 재질(Material)은 종이였다. 인류가 천 년을 사용해 온 재질을 은유하되 그보다 강력한, 마음대로 늘어나고 줄어들고 붙었다 떨어지는 마법의 종이.

매터리얼 디자인은 그림자 효과와 높낮이를 활용한다. 클릭될 수 있는 것은 돌출되어서 클릭될 수 있다고 알려주어야 한다.

매터리얼 디자인은 애니메이션을 활용한다. 현실세계에 워프와 순간이동은 거의 관측되지 않는다. 사물은 과정을 통해서 변해야 한다.

이러한 디자인 '언어'는 직관을 가능하게 된다. 종이, 누를 수 있을 것 같아 보이는 돌출, 애니메이션, 만질 수 있음 (tangible) 등등은 무엇이 될 것 같은지를 알 수 있게 한다.


따라서 애플의 스큐어모피즘이 작동하는 이유를 설명할 단어가 '직관성'이겠는가 메타포(은유) 이겠는가?


뮤직플레이어에 나오는 버튼을 클릭하자 버튼이 확대되면서 플레이 제어 화면이 되는 장면은 매터리얼 디자인이 스큐어모피즘보다는 좀 더 추상적이고 고차원적인 은유임을 보여준다. 스큐어모피즘은 주로 우리가 아는 사물을 모사하는데서 직관을 발생시킨다. 진짜 오디오처럼 동작함으로써 동작을 예측 가능하게 했을 것이다.

그러나 위의 예시는 현실에서 가능한 동작이 아니다. 그것은 추상적으로, 버튼이 확장된다는 점, 바로 그 버튼이 확장된 종이 위에 UI가 펼쳐졌다는 점에서 해당 버튼과 같은 맥락 위에 있다는 것을 보여준다. 이것은 현실의 모사가 아니고, 추상적, 논리적인 컨텍스트의 발생이다.


얼마나 많은 디자이너들이 이것을 이해할까? 잘 모르겠다. 스스로를 ux 디자이너라고 주장하는 사람들은 이제 매터리얼 디자인의 빌딩블럭을 손에 쥔 이상 정말로 자신이 디자인하는 것이 단순한 겉모양이 아니라 ux임을 증명해야 할 것이다. 그들은 애니메이션을, 그 애니메이션의 컨텍스트를 디자인해야 할 것이다.

ux의 흐름 그 자체에 대해서 별다른 생각을 해보지 않은 채, 그저 iOS 디자인을 열화카피한 디자인을 안드로이드에 적용시키는 기획자와 일하는 것은 꽤나 재미 없는 작업이었다. 난 극단적으로 냉소적인 사람은 아니지만, 솔직히 말하자면 이런 명료한 프레젠테이션이 발표된 이 순간 이후에도, 여전히 그런 기획자들이 대다수를 차지할 것이라고 생각할 정도로는 냉소적이다.

2014년 5월 31일 토요일

Android 개발자로 일하기 위해서 필요한 지식들

한동안 안드로이드 앱 개발자로 일하면서 생각했던 단계별로 필요한 지식들, 안드로이드 개발을 막 시작한 부사수가 있다면 이런 과정을 거치도록 유도할 것이라고 생각했던 것들입니다.

1단계 - 아직 일 못 맡기지만 좋은 시작

2단계 - 간단한 작업은 맡겨도 됨

  • UI thread를 이해할 것
  • race condition, deadlock, visibility 등을 이해하고 위의 세 가지 문제가 없는 AsyncTask를 작성할 수 있을 것.
  • 코딩 원칙 체화 - 디자인 패턴, SOLID, 메소드 짧게 짜기, 한 메소드 내에서 각 statement 들의 추상화 정도가 비슷한 수준을 유지하게 하기 등등
  • Activity, Service의 라이프사이클을 이해하여 이 부분에서 문제가 되는 해괴한 코드를 짜지 않음. (static 변수에 의한 leakage예시가 대표적)
  • http://developer.android.com/guide/index.html 에 있는  내용을 대체로 숙지

3단계 - 같이 일하기 즐거운 동료

  • LOGCAT, adb shell top, hprof, 프로파일러 등등을 이용해서 메모리 사용, CPU-배터리 사용을 최적화할 수 있음
  • Mark and Sweep 을 이해하고, Activity 내의 static 변수가 발생시킬 수 있는 과도한 메모리 사용, 비트맵의 recycle() 이슈 등 이미 잘 알려진 메모리 관련 이슈들을 알고 있음.
  • 최신 유행하는 오픈소스 라이브러리 동향을 파악하고 있음. 이미지 로더 짜놓고 나서 volley를 발견한 멍청하고 아픈 과거가 있음.
  • jni 를 이용하여, 네이티브에서 자바 오브젝트와 메소드을 접근하여 사용할 수 있음

4단계 - 내가 배워하는 분들

  • Android 내부를 잘 이해하여 zygote, Binder 등을 막힘 없이 설명할 수 있음.
  • aidl을 활용함
  • GC의 동작 특성을 이해하여 locality를 고려한 코드를 짤 수 있음

2014년 5월 2일 금요일

emacs + Golang

go-settings.el

(add-to-list 'load-path "~/.emacs.d/go-mode" t)
(require 'go-mode-load)

(add-hook 'go-mode-hook (lambda ()
                          (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)))
(add-hook 'go-mode-hook (lambda ()
                          (local-set-key (kbd "C-c i") 'go-goto-imports)))
(add-hook 'before-save-hook 'gofmt-before-save)

(add-to-list 'load-path "~/.emacs.d/go-autocomplete" t)
(require 'go-autocomplete)

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(magit-item-highlight ((t nil)) t))

;; go-flymake & go-flycheck
(add-to-list 'load-path "~/.emacs.d/go-flymake")
(require 'go-flymake) 

 

 .emacs 에 추가될 사항

(load "~/.emacs.d/go-settings")

2014년 4월 24일 목요일

TDD 단상

어제밤 중에 TDD 이야기가 나온 김에 그냥 내 삽질 끝에 내린 생각 정리.

테스트를 먼저 작성
켄트 백의 책이 던진 충격 중에 가장 도발적이고 강력한 것이 이것이 아니었을까 생각한다.

"아직 아무 코드도 없는 상태에서, 실패할 테스트를 먼저 작성한다."

이것이 가지는 부수적인 효과는 다음과 같은 것들이라고 생각한다.

 1. 코딩에 들어가기 전, 어떤 인터페이스, 다시 말해서 어떤 인풋과 어떤 아웃풋을 가져야 할지를 먼저 생각하고 코딩에 들어가게 한다. 다시 말해서 내부 구현이 아니라 behavior에 의존하는 코드를 짜도록 강요한다.
 2. 매 다음 단계마다 테스트가 작성되므로 테스트가 각 '단위별'로 만들어지게 된다.
 3. 2의 여파로 각 단위가 고립되서 테스트되어야 하고 결과적으로 디커플링이 중요한 문제가 된다. 나는 mock을 이용하는 테스트가 멋지다고 생각한다.

이것들은 모두 좋은 디자인을 강제하는 방법으로 보였었다. 어떤 면에서는 전통적이라고 볼 수 있는 부분들도 있다. 나는 C를 A book on C, The C Programming Language 등으로 했었는데, 이 시절의 책들에서 실제 코드를 하기 전에 하도록 권유하는 것은 (테스트 작성은 아니고) 주석 작성이었다. 이것이 결국 인터페이스를 먼저 생각하라, 구현보다 인터페이스에 의존해라 등의 가르침이 아닌가? TDD는 이에 더불어 자동화된 테스트를 보유함으로써 리팩토링과 동전의 양면을 이룬다. 테스트될 수 있기 때문에 바꿀 수 있다.


나는 코드의 한 부분에서나마 이것들을 모두 지킬 강인한 의지가 있다면 충분히 경청할만한 방법이라고 생각한다. 그러나 당연히 만능이 아니다. 나는 그 한계를 내적인 것과 외적인 것으로 구분한다.


내적인 것은 TDD 자체가 가진 한계다. TDD는 함수, 프로시져, 메소드 단위에서는 좋은 디자인을 강요한다. 그러나 어떤 메소드가 어느 클래스에 속해야 하는지, 그 관계가 정확한 메타포를 형성하는지를 생각하도록 강제하지는 않는다. Car 클래스에서 drive()를 가져도 되는가? Driver클래스는 따로 만들어서 drive()는 Driver가 하는 것이 나을 것이다. 그러나 drive()의 테스트를 작성하는 순간, 그 사람은 drive()의 인풋과 아웃풋에 대해서 고민하겠지만 drive()가 Car에 속하지 않도록 강제하는 단계가 뚜렸하지는 않다고 본다.

외적인 것은 외부적인 상황 때문에 마주치는 한계이다. 대표적으로 GUI 프로그래밍의 경우 현재까지 사용자 인풋을 자동화하는 뾰족한 방법이 나왔다고는 보기 힘들다.  쓰레드 safety 문제도 TDD가 적절한 해법이 되기 힘들다고 보는데, 사실 이 외적인 한계들은 내적인 한계와 완전히 무관하지는 않다. 하나의 메소드가 synchronous 하게 인풋을 아웃풋으로 전환시키는 상황을 벗어나는 테스트는 본질이 아니기 때문이다.

이러한 "쓰면 되레 손해인 영역들"을 경험으로 확인해 나가고 쌓이는 것이 결국 TDD로 이득 보는 것을 가능하게 할 것 같다.

UEFI-GPT 부팅환경에서 페도라가 자동 생성하는 파티션

sda                                                                 
├─sda1 vfat                     8ABA-40EB                            /boot/efi
├─sda2 ext4                     cc7ef53e-c22c-438b-a070-3063822e020a /boot
├─sda3 swap                     3e8be53f-78c9-40b7-8f03-603a3b480fc8 [SWAP]
└─sda4 btrfs  fedora_isyru-e135 87837358-656a-4cb4-80d7-740e80af83a0 /

 
 Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          411647   200.0 MiB   EF00  EFI System Partition
   2          411648         1435647   500.0 MiB   0700
   3         1435648         8808447   3.5 GiB     8200
   4         8808448       976773119   461.6 GiB   0700  


Arch, Gentoo같은 배포판 설치할 때 파티션을 어찌 설치해야 할지 모르는 상황에서 참고하기 위해서 씀.

2014년 4월 13일 일요일

emacs에서 git라면 역시 magit!!

emacs에서 git 사용은 당분간 magit로 쓰는 걸로 결정.

정확한 상황은 모르지만 emacs의 vc인터페이스가 기본적으로 git의

working directory - stage - commit

구조에 딱 들어맞지 않게 생겨 있는 게 아닌가 하는 생각이 들고, vc-git나 emacs-git나 이 문제에 있어서는 매한가지인 것으로 보임.

옵션 뒤지면 다 나올 수도 있겠으나, 뒤져야 나오는 건 그 자체로 문제.


그래서 당분간 magit를 쓰기로 했습니다. 우분투, 페도라 두 배포판 모두에서 제공됩니다.

2014년 3월 11일 화요일

my .emacs

(require 'color-theme)
(color-theme-initialize)
(color-theme-gnome2)

;;; ~/.emacs 에 다음을 수정 또는 추가하세요
(custom-set-variables
'(default-input-method "korean-hangul390")) ;; 세벌식 390



go-mode 설치 파트는 일단 패스