티스토리 뷰

에세이

toggleContentShare

June 2021. 9. 21. 02:05

2005년 초의 일입니다. 10일짜리 상병 정기 휴가를 나와서 3일 정도만에 만날 사람을 다 만나고 7일 정도의 의미 없는 시간을 보내던 저는 의미 없이 인터넷을 돌아다니다가 문득 소프트웨어 분야의 큰 별이 하나 졌다는 소식을 듣게 됩니다. 그의 이름은 재프 래스킨(Jef Raskin)이었고, 인터페이스 디자인의 대부였으며, 그 유명한 1984 매킨토시를 개발한 사람이었지만 프로젝트 도중 스티브 잡스와 크게 싸우고 팀을 나간 덕분에 이 분야에 어지간히 관심이 있지 않은 저 같은 사람에게는 다소 생소한 사람이기도 했습니다.

인터페이스 디자인은 잘 모르는 분야였지만 존경할만한 소프트웨어 거장이 - 내가 그 사람을 존경하기도 전에 - 사망했다는 소식을 접한 저는 아무래도 이 사람이 누군지 조금 더 자세히 알아봐야 존경과 안타까움의 정도를 구체화시킬 수 있겠다는 생각에 광화문 교보문고로 달려가서 그분이 생전에 저술한 책을 한 권 구입해왔습니다. 큰 서점이 아니면 팔지도 않았던 그 책은 인간 중심 인터페이스(Humane Interface)라는 제목을 가지고 있었으며, 디자인 전문 출판사에서 출판했기에 컴퓨터 관련 책답지 않게 디자인이 깨끗한 편이었고 두껍지도 않았습니다.

책을 들고 부대로 복귀한 뒤, 이 책에는 이해하기 어려운 그림과 도표, 수식들이 들어있기는 하지만 북한을 찬양하는 내용이나 자유민주주의를 위협하는 내용은 없다는 보안성 검토를 받은 뒤 무사히 관물대에 책을 꽂아둘 수 있었습니다. 핸드폰을 쓸 수도 없었고 (쓸 수 있다고 했어도 핸드폰으로 인터넷이 되던 시대가 아니라서 별로 달라질 것은 없었겠지만) 케이블 티비가 나오지도 않았고 PC도 없었던 부대는 전반적으로 일과시간 외에는 지루한 편이었고 특히 주말에는 정말 할 일이 없었습니다. 공놀이도 별로 좋아하지 않던 저는 정말 책을 읽는 것 외에는 할 일이 너무나 없었지만, 반입할 수 있는 책의 숫자에는 한계가 있었고 저는 읽었던 책을 또 읽고 또다시 읽는 것에 매우 익숙한 편이었습니다. 그리고 두껍지 않아서 금방 읽을 수 있었던 인간 중심 인터페이스도 예외는 아니었습니다.

솔직히 말하면 여러 번 읽을 수 밖에 없었던 것이, 한 번 읽고 나서는 도대체 무슨 소리를 하는지 이해가 되지 않았기 때문입니다. 초반은 그럭저럭 쉽게 읽히는 듯싶다가도 갑자기 이해가 안 되는 대목들이 생겨나기 시작하고 어딘가에서부터는 수학적인 계산이 시작되는데 계산 과정이 친절하게 기술된 것도 아니라서 생략된 부분들을 알아내기 위해서는 매우 많은 추론이 필요했습니다. 저는 부대에서 그 책을 한 다섯 번 정도는 읽었는데 솔직히 말하면 그 내용을 다 이해했다고 자신할 수는 없었습니다.

하지만 워낙 많이 읽었던 탓에 이 책에서 초반에 다루던 주제인 모드(Mode)와 단조성(Monotony)에 대해서는 어느 정도 이해할 수 있었습니다. 모드는 나쁜 인터페이스 디자인의 대표적인 산물로 사용자에게 많은 혼란과 오류를 불러오기에 가급적이면 사용하지 말아야 하고 무언가를 실행하기 위해서는 가급적 한 가지 방법만 존재해야 한다는 단조성의 원칙 같은 것들 말입니다. 우리에게 많은 혼란과 오류를 야기하는 대표적인 모드는 한/영키로 토글 하는 언어 모드가 대표적인데, 스마트폰과 같은 온스크린 키보드를 사용하여 현재 언어가 무엇이다라는 것을 사용자가 정확히 인지하기 전까지 우리는 키보드 사용의 숙련도와 무관하게 무수히 많은 '한글을 쳐야 하는데 영어로 치거나 그 반대의' 짜증 나는 상황을 감수해야 했습니다. 반대로 단조성은 직관적으로 이해하기 어려웠는데, 예를 들어서 파일을 저장하는 방식이 Ctrl + S / 저장 아이콘 클릭 / 메뉴 - 파일 - 저장 클릭과 같이 여러 가지로 존재할 것이 아니라 가장 효율적인 딱 한 가지 방법으로만 존재해야 사용자들이 혼란 없이 최적화된 습관을 형성할 수 있고 이로 인해 중독에 가까운 사용성을 가져올 수도 있다는 것입니다.

사실 소프트웨어 개발을 공부하던 입장에서는 뭐가 되었든 이것도 되고 저것도 되는 것이 편하다고 생각했기 때문에 단조적인 인터페이스가 편하다는 사실에 선뜻 동의하기는 어려웠습니다. 이후 애플에서 나온 아이팟이나 아이폰과 같은 제품들은 대부분 이 원칙을 지키기 위해서 노력하는 듯 했는데, 저는 와이파이를 바꾸기 위해서 항상 홈 버튼을 누르고, 설정에 들어가서 와이파이 항목까지 몇 단계를 타고 들어가야 하며, 다른 방법 - 안드로이드와 같이 와이파이 아이콘을 길게 누르는 등의 -을 허용하지 않는 애플의 디자인이 어째서 편하고 매니아적인 사용자들을 끌어들일 수 있는 디자인인지 이해하기 어려워했습니다.

하지만 소프트웨어 개발에 종사하기 시작하면서 저는 이를 디자인이 아닌 개발의 관점에서 바라보면서 어렴풋이 이해하게 되었습니다. 좋은 인터페이스 디자인을 위한 원칙들은 대부분 좋은 소프트웨어 개발을 위한 원칙과 이어져있었던 것입니다. 예를 들어서 개발하고자 하는 소프트웨어의 디자인에 모드가 존재한다면 이 모드에 영향을 받는 함수들은 항상 똑같은 형태로 동작하는 것이 아니라 모드에 따라 다르게 동작하는 분기를 만들어내야 합니다. 예를 들어서 키보드 a를 눌렀을 때는 모드에 따라서 ㅁ이 입력되기도, a가 입력되기도, A가 입력되기도 할 수 있는 것입니다. 이러한 분기는 소프트웨어를 만들 때, 설계, 개발, 테스트, 통합 과정에서 모두 엔트로피를 상승시키는 주범이 됩니다. 분기에 따라 동작이 3개가 될 수 있다는 말은 코드도 3배가 된다는 말이고, 테스트 케이스도 3배가 된다는 말이고, 이 코드를 가져다 쓰는 사람들의 입장에서도 고민이 3배가 된다는 말이기 때문입니다. 실력이 있는 개발자들은 어떻게든 이러한 분기를 수학적으로, 그러니까 모드를 고려하여 하나의 흐름으로 제어하기 위해서 노력하면서 좋은 코드를 만들어내려고 노력하지만 이는 매우 고차원적인 설계와 절묘한 코드 작성을 요구하기 때문에 기본적으로 꽤나 피곤한 일입니다.

하지만 소프트웨어를 만들 때 모드를 완전히 배제하는 것은 너무나 어렵습니다. 꼭 사용자 인터페이스의 관점에서만 생각하지 않더라도, 그냥 평범한 백엔드 프로그램을 만들 때에도 우리는 가끔 필요에 의해 모드를 만들고, 모드에 따라 다르게 동작하는 API를 만들어낼 때가 있습니다. 한/영키를 쓰지 않기 위해 한글 키보드와 영문 키보드를 하나씩 준비해서 쓰는 것이 보편적인 선택이 아닌 것처럼 때로는 일정한 효율성을 위해서 모드를 이용한 디자인이 필요한 경우가 꽤 있습니다. 사실은 거의 모든 개발에 모드는 들어가기 마련이고, 그것에 익숙하기에 앞에서 말했던 것처럼 개발자들은 고차원적이고 절묘한 개발을 위해 포도당을 다량 소모하는 것에 익숙한 편입니다.

문제는 이렇게 필연적으로 발생하는 모드에 단조적이지 않은 디자인이 들어가는 경우입니다. 어떤 모드를 변경하는 방법, 혹은 이 모드에 영향을 받는 동작이 다수가 된다면 이를 처리하는 코드는 굉장히 복잡해지게 됩니다. 예를 들어서 저희 집의 에어컨은 켜고 끄고 온도를 조절하는 방법이 리모컨을 사용하는 것밖에 없었기에 리모컨의 액정에 작동 상태와 현재 온도를 표시해주는 디자인을 채택할 수 있었습니다. 에어컨의 작동이 단조적이었으니까요. 하지만 리모컨이 하나 더 있는 경우, 혹은 요즘처럼 스마트한 기기들을 이용해서 외부에서 에어컨을 켜고 끄는 경우를 가정한다면 말이 달라집니다. 리모컨은 신호를 보내기만 할 뿐 받지는 못하기 때문에 다른 기기가 에어컨을 켜고 끄거나 온도를 조절하면 리모컨 액정에 표시된 정보는 현재 에어컨 상태와 불일치를 일으키게 되고 잘못된 정보를 전달하게 됩니다. 이를 해결하려면 아마도 리모컨의 설계와 내부에 들어가는 코드가 엄청나게 복잡해져야 할 겁니다. 지속적으로 상태를 확인하고 일치시키는 동작이 들어가야 하는데, 이는 버튼을 누르면 신호를 보내고 화면을 바꾼다는 단조적인 코드에 비해 월등히 복잡하고 만들기 어려운 코드가 되거든요.

하지만 다행히도 대부분의 에어컨들은 리모컨에 On/Off 버튼은 하나만 존재하더라도 신호는 켜는 신호와 끄는 신호를 구분해서 보내고 있습니다. 같은 전원 버튼을 누르더라도 리모컨이 생각하기에 현재 에어컨이 켜져 있으면 끄는 신호를 보내고, 꺼져있으면 켜는 신호를 보내는 것입니다. 단조성이 깨져서 이미 켜져 있는 에어컨에 다시 한번 켜는 신호를 보내더라도 엄청난 오류가 생기지는 않습니다. 켜져 있는 에어컨을 다시 켤 수는 없으니 실제 에어컨은 그저 리모컨의 신호를 무시하겠지요. 이러한 소프트웨어 인터페이스 설계는 너무나 당연한 것이라서 그렇게 특별한 것은 아닙니다. 사용자야 전원 버튼을 눌러도 반응 없는 에어컨에 잠깐 당황할 수는 있겠지만, 이것에 상태가 꼬여서 리모컨에서 표시하는 정보와 에어컨의 상태 사이의 불일치가 영원히 해소되지 않는 것에 비하면 훨씬 나은 설계이기 때문입니다.

그래서 저희는 어떤 함수를 설계할 때, toggle 어쩌고 하는 함수는 거의 만들지 않습니다. 만들더라도 이름만 토글이지 실제로는 뒤에 파라미터를 받는 경우가 대부분입니다. 만약 함수가 정말 파라미터 없이 toggleXXX() 이런 식으로 호출해야 한다면, 호출하는 입장에서는 현재 상태에 따라서 의도한 동작과 정반대의 동작을 유발할 수 있음을 감수해야 하는 리스크가 생기게 됩니다. 차라리 toggleXXX(boolean turnOn)과 같은 형태로 호출하는 사람의 의도가 켜는 것인지 끄는 것인지 명확히 하는 쪽이 훨씬 오류가 적은 커뮤니케이션이고, 저희는 대부분 그렇게 합니다.

그러니까 제가 toggleContentShare()라는 함수를 봤을 때, 느끼는 당혹감의 근원은 2005년까지 거슬러 올라가야 하는 것이었습니다. API 디자인은 더할 나위 없이 깔끔했습니다. 콘텐츠 셰어 기능이 꺼져있을 때 저 함수를 호출하면 기능이 켜집니다. 그리고 켜져 있을 때 저 함수를 호출하면 기능이 꺼집니다. 저는 그저 콘텐츠 셰어 버튼을 누르면 저 함수가 호출되도록 만들면 끝이었습니다. 저 SDK를 사용하는 개발자가 신경 쓸 것이 거의 없도록 만들어주는 매우 단순한 코드였습니다.

하지만 무척이나 신경이 쓰였습니다. 개발하는 입장에서는 startContentShare() / stopContentShare()처럼 명확하게 구분된 두 개의 함수가 제공되는 쪽이 훨씬 신경이 덜 쓰이는 편이었고, SDK를 제공해주는 입장에서야 두 개의 함수를 제공하는 것이 크게 어려운 일도 아니었습니다. 콘텐츠 셰어 기능이야 그 자체로 모드를 유발하는 기능이었기에, 그 모드를 켜고 끄는 함수가 toggle 형태라는 것이 말이 안 되는 것은 아니었지만, 제가 생각하기에 이 함수는 인터페이스 디자인의 모드를 소프트웨어 디자인의 모드까지 끌고 와서 오류 발생 가능성을 높여버린 최악의 함수였습니다. 그래서 저는 API 문서에서 저 함수와 그에 대한 설명을 보자마자 가쓰오부시로 두들겨 맞는 듯한 기분이 들었습니다. 그러니까 잘 모르는 사람에게는 별거 아닌 것처럼 느껴지겠지만, 뭔가 아는 사람에게는 심각한 타격으로 느껴졌다는 말입니다.

다행히도 콘텐츠 셰어 기능을 제어하는 함수는 toggleContentShare() 함수가 전부였기에, 그나마 단조적이었습니다. 그래서 저는 불편한 기분으로 현재 상태에 따라 toggle 함수가 의도에 맞게 동작하도록 감싸는 함수를 하나 더 만들어낼 수 있었고, 모드에 의해 유발되는 오류 발생 가능성을 대폭 줄여버릴 수 있었습니다. 하지만 네트워크를 타는 기능이었기에 저는 이 함수가 희박한 확률로 동시성에 의해 의도한 것과 다르게 동작할 수도 있을 것 같다는 불안감을 떨쳐버릴 수는 없었습니다. 몇 번이고 야! 아마존! 너네 진짜 개발 똑바로 안 할래? 정말 끝까지 속 상하게 만들래?라고 이슈를 올리고 싶어지는 충동을 억누르면서 개발을 마무리했습니다.

마무리한 코드를 저장소에 올리면서, 그런 생각이 들었습니다. 아는 만큼 보인다는 말이 있는데, 제가 지금까지 12년 동안 회사에서 돈을 받으며 개발하면서 알아차린 것들은 무엇이었고, 모르고 지나쳤던 것들은 무엇이었을지. 내가 잘 몰라서 지나친 것들 중에 치명적인 실수가 있지는 않았을지. 나는 정말로 최선을 다했는지. 받는 돈이 부끄럽지 않은 코드들을 올렸을지. 물론 코드가 올라가는 짧은 시간 동안 많은 생각이 드는 것은 자연스러운 일이었지만, 보통은 저녁에 뭐 먹을지에 대해서 고민하는 것이 대부분이었는데 이번에는 좀 더 진지한 생각들이 스쳐 지나갔습니다. 솔직히 말하면 업로드가 완료된 뒤에도 한참동안 생각에 빠져있었습니다. 아무래도 12년의 회사 생활을 마무리하는 마지막 기능의 마지막 코드를 올릴 때는 좀 진지한 감상에 빠져있어도 무죄가 아닐까 싶어서요.

그러다 문득 내가 놓친 것들은 꼭 코드에만 있는 것이 아닐 수도 있겠다는 생각이 들었습니다. 그래서 제가 지난 12년의 회사 생활 동안 몰라서 놓쳤던 것들이 무엇인지에 대해서 아주 잠깐 생각해봤다가, 그 아득한 스케일에 이내 질려서 고민을 멈추고는 그냥 저녁에 뭐 먹을지에 대해서 고민하기로 마음을 먹었습니다.

'에세이' 카테고리의 다른 글

너무 느리거나, 너무 빠르거나  (0) 2021.05.20
echo  (0) 2021.04.05
레디스(Redis)의 50가지 그림자  (5) 2021.03.14
보이지 않는 별빛에 닿아  (0) 2021.03.07
우리들의 분리수거는 뭔가 크게 잘못되었다  (0) 2021.02.14
댓글