Dec 21, 2017 - POP_part2

원칙 프로그래밍 가이드 라인

PIE(Program Intently and Expressively)

의도를 표현해서 프로그래밍 해라.

코드는 컴파일러가 아닌 사람이 읽기 위한것이다. 그래서 어떻게 하면 다른사람이 잘 이해하게 직관적으로 코딩하자.

코드는 소프트웨어 동작을 정확하고 완벽하게 알기 위한 유일한 실마리다. 소프트웨어개발중에 수많은 문서가 작성되지만 문서들만으로 소프트웨어가 어떻게 동작하는지 관해 정확하게 알수없다. 개발과 코드 동기화가 깨지는 경우도 빈번하고 만들어지는 문서들이 아주 상세한 내용까지 존재하지 않기 때문에 결국엔 코드를 읽어서 코드로 상세기능을 파악해야 된다. 그래서 코드를 읽는 시간이 많이 일어나고 이해를 해야되는데 직관적인 코드를 작성해야 된다.

코드는 읽기 쉬운것이 최우선이다.

코드를 작성할때 ‘작성하기 쉬움’보다 ‘읽기 쉬움’을 중시하자 코드는 작성하는 시간보다 읽는 시간이 훨씬 많은 법이다. 내가 작성을 하지만 그뒤로 유지보수한 시간만큼 많이 읽힌다. 코드는 실행 효율(성능)보다 읽기 효율이 우선시 된다. 읽기 쉬우면 나중에 성능을 높히는것도 그만큼 쉽다. 남이 읽은수 없는 코드는 좋은코드가 아니다 신기술이 아무리 좋아도 다른사람이 읽기 어렵다면 사용하지 않는것이 좋다.

두더지 잡기식 개발은 피한다.

빨리 개발하라는 온갖 압력에 직면하는데 읽기 쉽고 오류가 없으며 품질이 좋은코드를 작성하려면 시간이걸린다. 단기적으로는 손실로 보이지만, 두더지 잡기식 개발이 되지 않으므로 장기적으로 반드시 이익을 가져다 준다.

주석을 작성한다.

주석 없이도 읽을 수 있을 법한 이해하기 쉬운 코드를 작성하는 것이 이상적이다. 다만 코드는 어디까지나 what과 how, 즉 ‘무엇을 하는지’와 ‘어떻게 하는지’밖에 표현하지 못한다. why, 즉 ‘어째서 그것을 하는지’를 표현할려면 주석을 사용할 필요가 있다. 코드라는 문서를 읽는 사람과의 의사소통에 사용하는 것이다.주석을 수단으로 사용하자.

문학적 프로그래밍

문학적 프로그래밍은 코드 자체를 문서화하는 기법이다. java doc, swagger

참조


Dec 20, 2017 - circuit-breaker

circuit-breaker

소프트웨어에 대한 복잡도가 높아지면서 서비스에서 다른서비스를 호출하는 형태(예를들면 MSA 형태로 구성되어 API들을 호출하는 형태)들이 보편화 되어 서비스 되고 있다.

응용프로그램을 만들때 환경에서 발생할 수 있는 일시적 장애에 민감해야 된다. 장애에는 구성 요소 및 서비스에 대한 네트워크 연결의 순간적 끊김, 일시적인 서비스 사용 불가, 서비스를 이용 중일 때 발생하는 시간 초과 등이 포함된다.

위에 장애에 대응하기 위해 retry 패턴을 구현할수 있다.

아래 전략들을 사용하여 장애를 처리할 수 있습니다:

  1. 취소-장애가 일시적인 것이 아니거나 반복해도 성공하지 못할 가능성이 있을 경우, 응용 프로그램은 작업을 취소하고 예외를 보고해야 합니다. 예를 들어 잘못된 자격 증명을 제시하여 발생한 인증 실패는 몇 번을 시도하더라도 성공할 가능성이 없습니다.
  2. 재시도-보고된 특정 장애가 특이하거나 드문 경우, 네트워크 패킷이 전송되는 동안 손상되는 등 특이한 상황 때문에 야기되었을 가능성이 있습니다. 이 경우, 응용 프로그램이 실패한 요청을 즉시 다시 시도할 수 있는데 그 이유는 동일한 장애가 반복될 가능성이 낮고, 요청이 성공할 가능성이 있기 때문입니다.
  3. 지연 후 재시도. 보다 일반적인 연결 또는 사용 중 장애 중 하나로 장애가 야기될 경우, 연결 문제를 시정하거나 작업 백로그가 비워지는 동안 네트워크나 서비스에 잠깐의 시간이 필요할 수 있습니다. 응용 프로그램은 요청을 재시도하기 전에 적절한 시간 동안 기다려야 합니다.

위에 retry 패턴을 구현해도 문제점이 생길수가 있다.

상당 수의 재시도 후에도 요청이 계속 실패하면, 즉시적으로 장애로 판단하고 처리 하는것이 좋다. 하지만 위에 정책만으로는 문제점들이 존재하게 된다. 이럴때 circuit breaker 패턴을 참조해서 구현하는것이 좋다.

circuit breaker 패턴는

  1. 폐쇄-응용 프로그램의 요청이 작업에 전달됩니다. 프록시는 최근 실패 횟수의 카운트를 유지하고 있다가 작업의 호출이 실패하는 경우 실패 횟수 카운트를 하나씩 늘립니다. 최근 실패 횟수가 지정된 시간 이내에 지정된 임계값을 초과하면 프록시는 개방 상태로 전환됩니다. 개방 상태로 전환된 프록시는 시간 초과 타이머를 시작하고, 시간 초과 타이머가 만료되면 프록시는 반개방 상태로 전환됩니다. (시간 초과 타이머는 응용 프로그램이 작업의 수행을 다시 시도하기 전에 먼저 시스템이 실패의 원인이 되는 문제를 해결할 시간을 확보하기 위한 것입니다.)
  2. 개방-응용 프로그램의 요청이 즉시 실패하고 예외가 응용 프로그램에 반환됩니다.
  3. 반개방-응용 프로그램으로부터 제한된 횟수의 요청이 통과되어 작업을 호출할 수 있게 됩니다. 이와 같은 요청이 성공하면 이전에 실패를 유발한 장애가 해결되었다고 판단하여 회로 차단기가 폐쇄 상태로 전환되고 실패 카운터가 초기화되지만 이와 같은 요청이 실패하면 장애가 여전히 남아 있다고 판단하여 회로 차단기가 다시 개방 상태로 되돌아가고 시간 초과 타이머를 다시 시작해 시스템이 장애를 복구할 추가 시간을 확보합니다. (반개방 상태는 복구 중인 서비스가 요청으로 인해 갑자기 서비스 장애를 일으키는 것을 방지하는 데 유용합니다. 복구가 진행되는 동안 서비스는 복구가 완료될 때까지 제한된 양의 요청을 지원할 수 있지만, 복구가 진행되는 동안 엄청난 양의 작업이 요청되면 서비스의 시간 초과 또는 실패가 다시 초래될 수 있습니다.)

위에처럼 상태를 나눌수 있고 거기에 따른 문제점 및 해결 방안을 고려 해야 된다.

해당 패턴을 구현하기 위해 넷플릭스에서 오픈소스를 내 놓은것이 Hystrix가 있다.

참조


Dec 20, 2017 - POP_part1

the_principles_of_programming

전제 프로그래밍 불변사실

프로그래밍에서는 은총알은 없다.

왜? 본질적으로 소프트웨어는 난해하다.

  1. 복잡성
    • 규모가 크면 수천 수만라인의 코드도 존재 하고 각 컨퍼넌트간에 종속성도 비선형적으로 증가함
  2. 동조성(호환성)
    • 실세계랑 끊임없이 동조 해야 된다. (네트워크, 하드웨어, 다른소프트웨어 등등)
  3. 가변성
    • 요구사항이 끊이 없이 바뀌기 때문에 코드 변경이 수시로 일어남
  4. 비가시성
    • 눈에 보이지 않은 개념들의 집합이 소프트 웨어임

소프트웨어의 역사나 기법들을 익혀서 복잡성을 줄여 나가야 된다.

코드는 설계서이다.

소프트웨어 개발중 작성된 모든 문서중 엔지리어닝 문서는 코드 이다.

코드가 설계를 하고 컴파일러가 컴파일해서 제조를 담당한다.

그래서 우리의 개선대상은 코드이다.

그래도 모든문서가 쓸때 없는것은 아니다.

코드에는 how와 what은 표현되어 있지만 why가 없다.

설계이유를 문서에 잘기록해 두자.

코드는 항상 변경된다.

코드는 한번 작성했다고 그것으로 끝이 아니다. 나중에는 반듯이 변경된다.

소프트웨어는 위에서 말했듯이 본질적으로 복잡하다. 배포된 후에 반드시 오류가 발생하고 오류를 해결해야 된다.

변경에 강한 코드를 작성하자 변경에 강한코드란 읽기 쉬운 코드이다. 코드는 사람이 읽기 쉽게 나온 언어로 결국엔 작성하는 시간보다 변경에 의해서 읽는 시간이 훨씬더 길다.

원칙 프로그래밍 가이드 라인

KISS(Keep it simple, stupid/Keep it short and simple)

코드 작성의 최우선을 간결함에 둔다.

코드를 생각 없이 수정하다 보면 저절로 무질서해지고 복잡해진다.

복잡한 코드는 읽기 어렵고 수정하기 어렵다.

코드에 불필요한것을 하지 않는다.

  1. 신기술 사용 - 신기술을 배우고 나면 불필요하게 코드를 작성할때가 있다. 코드는 두뇌의 명석함을 뽑내기 위한것이 아니라 사용자에게 가치를 제공하는것이다 정말 필요한것인지 생각하고 코드를 단순하게 유지하자
  2. 장래의 필요에 대비 - 나중에 필요할지도 몰라서 오버엔지니어링을 하는경우가 있다 지금 꼭필요한 코드만 작성하자 그래서 코드의 단순함을 유지하자.
  3. 멋대로 요구사항을 추가 - 멋대로 요구사항을 판단해서 불필요한 코드를 추가할때가 있다 꼭 사용자한테 요구사항을 판단해서 불필요한 코드를 작성하지 말자.

less is more 단순한 것이 더 아름답다 건축분야에 쓰는 말인데 소프트웨어에도 딱 들러맞는다.

개인적인 생각으로 초기 소프트웨어 공학이 건축분야에서 많은것을 차용했는데 비슷한 부분이 많아서 그런게 아닌가 싶다.

DRY (Don’t Repeat Yourself)

코드 복사 붙여넣기는 금물(?) 이렇게 되면 같은로직이 여러군데 흩어지는 경우가 생긴다.

코드 개선할 수 가 없다.

  1. 코드를 읽는 작업이 어렵다
  2. 코드를 수정하는 작업이 어렵다
  3. 테스트가 어렵다.

중복을 줄이는 법은 코드를 추상화 하자 하지만 기존 코드를 건들어야 되니 잘못 수정할수 있다. 그리고 귀찮다. 하지만 중복이 좋지 않다는것은 반론의 여지가 없다 리팩토링 하자

DRY의 적용 범위 소프트웨어 개발 전반적으로 다 적용 되어야 된다 지속적인통합 이야기도 결국에는 개발자가 빌드하고 디플로이하는 중복작업을 줄이는면에서는 DRY원칙이 적용 되었다고 보면된다.

프로그래밍 언어에서도 대부분 DRY를 실현하려고 객체지향이나 함수형 프로그래밍 에서 처럼 중복 제거 기법이 다 녹아들어가 있다.

불가피한 DRY 위반이 있을수도 있다. 불일치가 발생하기 쉬운 부분은 추상화 스타일이 서로 다른 경계선이다.

DRY <-> WET(Write Every Time/Write Everything Twice) 건조함과 촉촉함

데이터 베이스에서는 One Fact in One Place(OFOP) - 일본에서 유명한 말인듯 모델링 쪽에 말인지는 모르겠지만 onefact.net 파피루스 만든 애들인듯

Once And Only Once(OAOO) DRY 보다 적용 범위가 좁고 프로그래밍에서만 사용됨

레거시 코드란 테스트코드가 없는 코드를 레거시 코드라 부른다 예전에는 ‘오래전에 만들어진 이해할수 없고 변경하기 어려운 코드’를 조롱하는 속어 였는데 지금은 테스트가 중요해지면서 테스트코드가 없는코드를 레거시 코드라고 한다. 이런 정의가 지나지체 엄격한 구분이라 생각할수는 있지만 테스트 없이 코드를 변경하는 것은 위험한 도박이기 때문이다. 일단 레거시 코드를 상대하게 되었다면 일단 테스트 코드부터 작성하자.

YAGNI (You Aren’t Gonna Need It)

코드는 필요할때 최소한으로 작성하자

코드는 항상 예측을 벗어난다. 미리 여러가지 상황을 대비해둬도 예측을 벗어나는 경우가 태반이다 확장성을 고려해서 작성 하면 오히려 코드 복잡성을 낳기 마련이다. 나중에 보면 사용하지 않는 코드이고 왜이렇게 작성한지 모르는 일이 태반이다. 열심히 고려한 설계가 무용지물일 뿐만 아니라 오히려 방해물이 된다.

그러면 코드 작성시에 선택방법이 범용성보다 단순함을 우선에 둔다. 위에 KISS에서 설명한 최우선 원칙이다. 나중에 요구사항이 늘어나도 복잡한 코드를 수정하는것 보다 단순한 코드를 수정하는것이 더 편하다.

YAGNI 코드에만 국한되는 말이 아니라 소프트웨어 기능에도 해당 된다. 풍부한 기능은 매력적으로 보이지만 ‘과녁에서 빗나간’ 기능은 사용하지 않을 뿐만 아니라 전체 사용법을 복잡하게 만들고 사용성을 떨어뜨린다.

Do The Simplest Thing That Could Possibly Work(dtsttcpw) 효과있는 방법중 가장 간단한 방법으로 하라

참조