R&R – Dreaming for the Future 영원한 개발자를 향해서. 월, 13 1월 2025 13:44:09 +0000 ko-KR hourly 1 https://wordpress.org/?v=4.7 108384747 리더십의 리더 – 같음과 다름 /index.php/2024/07/07/equality-and-inequality-in-leadership/ Sun, 07 Jul 2024 13:25:01 +0000 /?p=1246

Continue reading ‘리더십의 리더 – 같음과 다름’ »]]> 인간은 평등하다. 공동체의 일원으로 우리는 모두 같은 존재다. 동등하기 때문에 서로 존중하고 존중받아야 한다. 그리고 특정 목적을 달성하기 위해 조직으로 함께 일한다. 개인이 추구하는 각각의 목표는 다르겠지만, 조직에 속한다면 당연히 조직 목표에 기여하고 성과를 만든다.

기업 입장에서 구성원이 목적 달성에 적극적이길 원한다. 결과 혹은 성과를 달성하기 위해 구성원 사이에 충분한 소통이 빠르게 일어나길 기대하고,  여러 실리콘밸리 빅테크(Big Tech) 기업의 성공 사례처럼 단방향이 아닌 양방향 소통이 결과 달성을 위해 효과적임을 알고 있다. 이런 영향으로 양방향 소통 방식의 기업 문화가 “수평 조직”이라는 체계로 불리며 많은 국내 기업이 도입하고 있다.

수평 조직을 실행하는 여러 방법 가운데 하나로 많은 회사가 영어식 이름 혹은 별명(Nickname)을 활용하고 있다. 대부분의 스타트업은 이런 호칭 방식을 유행처럼 사용하고 있고, 쏘카의 경우는 별명을 사용하면서 “~님”이라는 높임 호칭까지 없앴다. 극단으로는 서로 반말을 쓰게 하는 회사도 있다는 이야기도 들어봤다. 일부 국내  대기업도 연차에 따른 직급 체계를 없애고 매니저, 프로, 책임과 같은 단일 호칭 체계를 사용하기도 한다. 그만큼 빅테크 혹은 기술 기업의 성공 배경에는 자유로운 소통이 큰 역할을 했다는 것을 인정하고 있다.

인터넷 출현 이후의 연결성(Connectivity) 기반의 사업은 변화에 대한 빠른 대응을 요구한다. 그리고 구글, 넷플릭스와 같은 빅테크 기업들의 성공 신화의 바탕에는 치열한 토론 문화가 자리잡고 있음은 분명한 사실이다. 토론을 통해 현재 사업 모델을 지속할지 아니면 변화할지, 변화한다면 어떤 방향으로 피봇(Pivot)할지 결정한다. 많은 아이디어와 이를 실현시킨 다양한 제품은 자유로운 토론 문화에서 탄생했다는 것에 동의한다.

수평 조직과 문화

실리콘밸리의 자유로운 토론 문화는 미국, 특히 실리콘밸리가 위치한 미국 서부의 지역적인 특성이 큰 몫을 차지한다. 미국은 이민자에게 기회의 땅이고, 귀족 계층이 사회 주류를 차지하던 동부 지역에 비해 골드 러시(Gold Rush)를 통해 개발된 서부 지역은 일반 서민 계층에 의해 발전되었다. 그만큼 개인 능력을 중시하는 사회 문화를 가졌으며, 능력이 사람을 판단하는 가장 큰 기준이 된다. 여기에 더해 미국인이 사용하는 영어는 기본적으로 “높임”이라는 개념을 갖고 있지 않다. 물론 존경을 표현할 수 있지만, 일상 대화에서 잘 모르는 상대방은 그저 상대방일 뿐이다. 대화 과정에서 자신의 의견과 함께 감정 표현이 언어적으로 자유로운 편이다.

미국 동료들과 시스템 구조에 대한 의견을 여러 사람과 함께 논의할 기회가 있었는데 한 미국 동료가 “Fuck”이라는 욕을 하는 것을 들었다. 순간 깜짝 놀랬는데, 회의 후에 참석했던 다른 미국 친구에게 그 단어를 듣고 놀랐다고 이야기했더니 그 단어는 단순한 감정 표현이였는데 어떤 점이 걸렸는지 되물었다. 곰곰 생각해보니 그 단어 출현 이후에도 원할하게 이야기가 오고갔고, 모두가 합의한 결과가 도출되었다. 답해준 친구에게 한국에서는 “Fuck” 이라는 영어 단어는 욕으로 상대방을 비난하는 단어로 인식하고 있었는데 공식적인 회의 자리에서 그 단어를 듣고 놀랐다고 이야기해줬다. 단어의 의미가 학습한 문화권에 따라 다르다는 것을 제대로 느끼게 된 계기였고, 자칫 사람을 오해할 수도 있었다. 덕분에 나도 대화에서 “Fuck” 이라는 단어를 필요할 때 사용할 수 있다.

실리콘밸리와 달리 우리 나라는 역사적으로 유교가 오랜 시간 사회 지배 문화였고, 나이든 어른을 존중하는 문화다. 현재의 발전된 사회를 이룩한 어른들(시니어)의 노력을 존중하고, 경험을 경청하는 것은 서구 사회도 부러워하는 문화다. 다만 어른이 나이와 동일시되면서, 나이가 어린 사람이 연장자에게 할 말 하는 것이 “버릇없음”이라는 사회적 인식이 자리잡있다. 당연하게도 나이어린 사람에게는 경청이 강요되고, 의견이 묵살되기도 한다. 특히나 한국어에는 어른에 대한 존중이 언어적으로 반영되어 있다. 나이 많은 분께 어린 사람이 반말을 했다고 시비가 일어나기 쉽고, 심한 경우에는 사회면 뉴스로 등장하기도 한다.

조직이 결과를 만들고 다음 성장을 이루려면 양방향 소통과 치열한 토론은 반드시 필요하다. 양방향 소통이 될려면 소통 당사자 사이의 높이 차이를 줄여야 한다. 높이차는 존재하지만 인위적으로 차이를 낮추기 위해 필요한 것이 존중이다. 한국 문화를 고려할 때, 직책자 혹은 “어른”이 보여주는 존중은 상대방이 한걸음 더 다가설 용기를 준다. 조직 피라미드의 상위자는 눈높이를 맞추기 위해 허리를 굽혀야 한다. 그리고 시니어의 경험을 주니어가 존중해야 한다.  상호 존중을 기반으로 이뤄지는 토론이 건강한 토론이고, 이런 토론들이 쌓여 조직은 현재와 다음을 결정된다.

수평 조직을 통해 우리가 달성하고 싶은 것은 양방향 소통이 동작하는 참여와 토론이다. 참여자 사이의 벽을 허물고 높낮이 차이를 줄여야 한다. 소통의 흐름은 어느 누구의 노력보다도 조직 피라미드의 상위에 있는 리더십의 역할이 중요하다. 수평 조직은 호칭 체계를 없앤다고, 영어 이름을 도입한다고 되는게 아니다. 먼저 리더십에서 허리를 굽히고 구성원에게 다가가야 한다. 구성원이 이야기할 수 있는 분위기(환경)을 조성하고, 실제로 이야기가 나왔을 때 끊지 않고 들어야 한다. 그래야 수평 조직을 위해 한걸음 나갈 수 있고, 조직이 달성해야 하는 결과를 위해 구성원이 실행 의지를 갖고 참여한다.

수평 조직의 오해

조직 계층의 아래 단계에 있는 구성원이 억지로 눈높이를 맞추기 위해 디딤돌을 놓거나 눈높이를 무시하는 경우도 있다. 2000년대 중후반에 호칭 체계를 없애거나 영어식 이름을 국내 기업들에서 도입하면서 이런 부작용이 실제 발생하기도 했다. 과감한 시도였지만 한국 문화를 간과한 면이 적지 않았다. 막 입사한 신입 직원이 10년 이상 경력의 동료에게 같은 매니저라는 점을 내세우며 자신의 입장을 강하게 주장하는 경우를 여러 번 목격했다. 이런 경우가 반복되고 용인되면 상대방인 시니어는 정나미가 떨어지기 마련이다.  주장이 맞는지 여부를 떠나 우리가 살고 있는 곳은 미국이 아니다. 한국에서 “Fuck”은 욕이라는 점을 잊으면 안된다.

조직은 목표를 추구,하고, 결과를 만들어 목표를 향해 나간다. 그리고 수평 조직은 양방향 소통과 치열한 토론을 통해 우리가 목표 달성을 위해 어떤 결과물(What)을 어떤 방식(How)으로 만들어낼지 정한다. 소통과 토론을 통해 무엇과 어떻게를 정하는 이유는 집단 지성을 활용하기 위함도 있지만, 무엇보다도 구성원의 적극적인 참여를 원하기 때문이다. 소위 자율성과 주도권을 기대한다.

하지만 수평 조직이 강조되다 보면 합의에 이르기 위한 무한대 토론이 반복되는 경우를 목격한다. 각자가 내세우는 의견이 합의점을 찾지 못하고, 자신의 논리로 상대방을 납득시켜 본인의 의견이 모두의 방향이 되도록 시도하는 경우다. 심지어 과도한 의견 대립은 파벌을 만들기도 한다. 이런 경우가 발생하면 리더는 반드시 개입하고 결론을 조율하거나 결정을 내려줘야 한다.

수평 조직의 모두는 평등하지 않다. 특히 조직의 리더는 조직과 조직의 결과를 책임진다. 책임자이기 때문에 의사 결정자이다. 조직이 만들 결과물은 필요한 시점에 존재해야 한다. 리더는 토론을 통해 도출된 합리적인 결과를 존중해야 한다. 그러나 결론 도출이 안된다면 리더가 조직을 대표해 결론을 내려야 한다. 그런 리더의 결정을 구성원 모두는 존중하고 따라야 한다. 그럼에도 따를 생각이 없는 구성원이라면 해당 조직의 일원으로 역할 수행 의지가 없는 것과 다름없다. 투명하게 본인 생각을 리더와 상위 리더에게 이야기하고 자신이 제대로 기여할 수 있는 다른 역할을 찾는 것이 좋다.

]]> 1246
TDD를 하신다구요? /index.php/2016/03/16/omg-are-u-doing-in-tdd/ Tue, 15 Mar 2016 15:25:02 +0000 /?p=35

Continue reading ‘TDD를 하신다구요?’ »]]> 사람들과 전화너머로 이야기를 하다보면 TDD를 자신있게 말하는 분들을 종종 만난다.  물론 이 분들의 이력서에도 “활용 가능한 기술”들 가운데 하나로 TDD라는 3글짜 알파벳이 강렬하게 적혀있다. 개인적으로 TDD 방식의 개발의 예찬론자이기도 하기 때문에 이런 분들을 만날 때마다 반가운 생각이 든다.

처음 이 단어를 들었던 때가 아마도 2010년도 쯤이었을 것 같다. 주변의 개발자들 가운데 아는 사람도 적고 해서 손에 익히기에 쉽지 않았다. 지금은 거의 대부분의 이력서에 언급될만큼 보편적인 것이 되버렸다고 생각했다.

하지만 이런 분들을 만나서 “TDD 방식으로 코드를 작성해봐주세요~” 하면 다른 양상이 펼쳐진다. 테스트가 개발을 주도하는 모습을 기대했지만 대부분 테스트는 장식이다.  이 모습을 보면서 아래와 같은 생각을 해본다.

왜 이런 의미없는 테스트를 작성할까?

테스트를 작성하는게 테스트 주도 개발인가?

뭔가 착각이 있는 것 같다. 원래 테스트와 테스트 주도 개발은 다른 건데 말이다.

시작이 문제다.

2차원상의 좌표 점들의 거리를 계산하는 프로그램을 작성해야 한다고 치자. 뭐부터 작성해야할까?

public class DistanceCalculator {
  public void addPoints(int x, int y) {
  }
  public float calc() {
    return -1;
  }
};

테스트를 먼저 한다고 하지만 그래도 이정도는 먼저 찍어놓고 해야겠지?  본능적인 촉에 의하면 2차원 좌표점이라고 이야기를 했으니까 그건 x, y로 표시해야하고, 점들이 많을테니까 이걸 관리해야하는 기능도 필요할테니 점들을 넣을 수 있는 addPoint(x, y)와 같은 메소드도 필요하다.  그리고 이것들을 가지고 계산을 해야하니까 당연히 calc() 라는 메소드도 있어야 한다.  TDD로 개발하는 개발자니까 구현은 테스트를 작성한 다음에 하는거지!!!

이렇게 하는게 과연 Test Driven일까?  하지만 이 코드는 이미 Developed 되어있다.  해야할 일은 채워넣는 일일뿐.  여기에서 테스트가 하는 일은 이미 구조가 잡힌 코드의 안정성을 보장하는데 사용된다.  물론 예외등을 테스트하다보면 코드의 발전을 이끌 수는 있겠지만, 완전한 Driven이라고 이야기는 어렵다.

테스트 먼저

TDD를 좋아하는 개발자라면 시작은 DistanceCalculator 클래스가 아니라 DistanceCalculatorTest 클래스에 대한 코드부터 적어야 한다.

public class DistanceCalculatorTest {
  @Test
  public void shouldItCalculateDistance {
  final Point start;
  final Point end;
  final float expectedDistance = 1.0f;

  GIVEN: {
    start = new Point(0, 0);
    end = new Point(0, 1);
  }

  WHEN: {
    calculator = new Calculator();
    actualDistance = calculator.distance(new Point[] { start, end });
  }

  THEN: {
    assertThat(actualDistance, is(expectedDistance));
  }
};

이 테스트 코드를 통해 우리가 많은 것들을 정리할 수 있다.

  • 계산을 수행할 객체의 이름을 정했다. DistanceCalculator 보다는 Calculator가 현재의 컨텍스트에서 좀 더 좋겠다는 생각이 들었다.  (물론 테스트의 이름도 변경하는게 맞지만 예제를 위해…)
  • 계산을 수행하기 위한 메소드는 2차원 좌표를 기술할 수 있는 Point 객체의 배열을 받는다. addPoint등을 생각할 수 있지만, 그렇게 하면 테스트 코드를 작성하는게 번거로워진다. 테스트 자체를 통해 메소드의 사용성을 평가하고 쉽게 사용할 수 있는 방향으로 메소드를 설계한다.

여기까지를 정리했다면 이제 메인 코드를 작성할 때이다.  이클립스나 IntelliJ에서 제공해주는 Code Complete 기능을 사용하면 순식간에 찍어낸다.  위 두가지 과정에서 볼 수 있는 건 우리가 작성할 코드의 방향과 형태를 테스트를 작성해봄으로써 끌어냈다라는 것이다.  이것이 Test Driven의 진정한 모습이다.

이제 실패하는 테스트를 통해 로직을 완성하면 된다.

나누고 끄집어내라

자 우리의 말썽많은 고객분께서 요구 사항을 바꿨다.  2D 세상에 만족을 못하고 3D 세상에서도 거리를 계산해달라고 한다.  테스트를 다시 한번 살펴보자.

  WHEN: {
    ...
    actualDistance = calculator.distance(new Point[] { start, end });
    ...
  }

distance 메소드가 수행하는 역할(Responsibility)를 정리해보자.

  • 인접한 두 Point 간의 거리를 계산하고,
  • 계산된 결과값의 합을 구하는 역할을 한다.

2D, 3D일지의 문제는 첫번째 “인접한 두 포인트간의 거리”에만 영향을 미친다. 나머지 기능은 원래 distance 메소드가 수행하는대로 하면 된다. 두 점 사이의 거리 계산 부분을 수행하도록 Point 객체에게 위임해버리면 된다.

한방에 끝낼려고 하지 말자

인접 점들 사이에 거리를 어떤 방식으로 distance 메소드내에서 수행되어야 할지를 결정해야 한다. 이걸 어떻게 할지를 테스트를 통해 적절한 구조와 로직을 찾아보자.

public void Space2DPointTest {
  @Test
  public void should2DPointCalculateDistnaceWithOhter() {
    final Point p1;
    final Point p2;

    GIVEN: {
      p1 = new Space2DPoint(0, 0);
      p2 = new Space2DPoint(0, 1);
    }

    final float actual;
    THEN: {
      actual = p1.distance(p2);
    }

    final float expected = 1.0f;
    THEN: {
      assertThat(expected, is(actual));
  }
}

테스트 코드를 통해 포인트에 대한 구조를 아래와 같이 잡으면 된다는걸 알 수 있다.

  • Point라는 인터페이스를 둔다.
  • 인터페이스는 Point 객체를 파라미터로 받는 distance라는 메소드를 정의한다.
  • Space2DPoint 클래스는 Point 인터페이스를 구현한다.

비슷한 맥락에서 Space3DPoint에 대해서도 테스트 클래스를 작성해보자. 두 테스트에서 동일한 구조로 동작이 가능함을 확인한다.

확인이 완료됐다면 다시 원래의 CalculatorTest 클래스로 돌아가 이를 수정한다. 현재까지 작성된 테스트들의 관점에서 우리는 GIVEN 영역을 아래와 같이 수정하면 된다.

  GIVEN: {
    start = new Space2DPoint(0, 0);
    end = new Space2DPoint(0, 1);
  }

그리고 원래의 Calculator.distance() 메소드를 아래와 같이 변경한다.

public float distance(Point[] points) {
  ...
  for (int i=1; i<points.length; i++) {
    distanceSum += points[i-1].distance(points[i]);
  }
  ...
 return distanceSum;
}

흠… 이 과정이 리팩토링이다. 알흠답다. ^^;

끝날때까지 끝난게 아니다.

여러분이 만드는 서비스/제품이 계속 사용자들을 만난다면 여러분의 개발은 끝난게 아니다.

변화는 필수적이며 변화에 대응하기 위한 테스트와 이에 상응하는 리팩토링 역시 지속되어야 한다.  이 과정을 반복함으로써 여러분의 코드의 날이 날카롭게 빛날 것이다.

 

ps. 조금 더 긴 있다.  내용이 썩 맘에 들진 않지만 그래도 노력이 있으니까 한번 봐주길 바란다. 언젠가 기회가 된다면 이 글도 제대로 손을 봐야할 듯 싶긴 하다.

]]> 35