chap02.원칙 - 프로그래밍의 가이드라인

chap02.원칙 - 프로그래밍의 가이드라인

[프로그래밍의 정석]을 보고 메모한 부분을 정리했습니다.

목차

  1. KISS :: Keep It Simple, Stupid
    • 오컴의 면도날
  2. DRY :: Don’t Repeat Yourself
  3. YAGNI :: You Aren’t Going to Need it
  4. PIE :: Program Intently and Expressively (의도를 표현해서 프로그래밍하라)
  5. SLAP :: Single Level of Abstraction Principle (추상화 수준의 통일)
  6. OCP :: Open-Closed Principle (개방-폐쇄의 원칙)

서론


1. KISS _Keep It Simple, Stupid

*코드는 단순하게 유지한다.

*why_아무생각 없이 수정하게 되면 코드는 무질서로 향한다.

함수의 경우 관심사 분리를 목표로 간결하게 유지한다.

  • 단순한 코드는 읽기 쉽고 수정이 용이하다.
  • 의사소통 유지비용을 절약할 수 있다.

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

단순함을 프로그래밍의 나침반으로 삼자.

아래 상황을 경계하자.

  1. 새롭게 배운 기술을 사용하고 싶다.
  2. 장래의 필요에 대비하고 싶다.
    지금 필요할게 아니면 지금 작성할 것이 아니다.
  3. 멋대로 요구사항을 추가한다.
    요구사항을 결정하는 쪽은 사용자다. 프로그래머가 요구사항을 결정해서는 안된다.

    케바케일듯

*Less is more 단순한 것이 더 아름답다.

지금 작성하는 코드가 정말로 필요한지를 항상 자문자답해야한다.

*오컴의 면도날

어떤 상황을 설명하는 데 필요 이상으로 많은 전제를 가정해서는 안된다는 사고방식.
= 뭔가에 관해 여러 가지 설명이 가능하다면 가장 단순한 방식이 옳다.


2. DRY

*코드 복사는 금물

  • 로직 한 덩어리를 다른 부분에 복붙
    • 같은 로직이 여러 군데로 흩어진다.
  • 같은 조건을 다루는 제어문 블록이 여러군데 중복
  • 같은 의미의 값(상수, 정수..)

*why_코드를 개선할 수 없다

  1. 코드를 읽는 작업이 어려워진다.
    양적으로 많아지고 질적으로 복잡해진다.
  2. 코드를 수정하는 작업이 어려워진다.
    신중하게 수정하지 않으면 수정에 누락이 생길 위험성이 있다.
    미세한 차이가 있다면 코드를 더욱 깊게 읽어야한다.
  3. 테스트가 없다.
    열심히 수정하더라도 테스트가 없는 상태에서는 새로운 오류가 발생할 위험이 커진다.

*how_코드를 추상화한다.

코드를 추상화함으로써 중복을 제거하자.
코드 로직을 추상화하려면
처리하는 코드를 묶고 이름을 붙여 함수화, 모듈화한다.

추상화의 장점

  • 코드의 양이 줄어 읽는 양을 줄일 수 있다.
  • 이름을 붙였으므로 코드가 읽기 쉽다.
  • 같은 코드를 한군데 집약했기 때문에 코드 수정이 용이, 품질을 담보하기 쉽다.
  • 추상화한 부분은 재사용하기 쉬워진다.

*DRY의 적용범위

구체적으로 반복되는 작업은 자동화

  • 자동화의 대표적인 작업 테스트, 빌드, 배포 (지속적인 통합)
  • 빌드, 테스트, 배포 등을 정확하고 빈번하게 자동 실행하는 것.
  • 장점
    • 반복 수작업이 없어진다.
    • 빌드 품질이 안정된다.
    • 빌드가 속인화하지 않는다.
    • 문제를 조기에 발견할 수 있다.

*DRY와 프로그래밍 기술

코드 중복을 제거하는 것을 목적 중 하나로 삼고 있다.

  • 구조화 프로그래밍

  • 객체지향 프로그래밍 기술
    함수나 모듈 구성을 통해 중복을 제거하기 위한 기법이 내제되어있음.
  • 디자인 패턴
    : 코드를 재사용 가능(확장가능)하게 하려고 코드 구조 패턴을 제공한다.
    사고의 중복이 일어나지 않게 하는 기법이라고도 할 수 있다.
  • 일반적으로 기술이나 기법은 특정 목적을 갖고 고안된다.
    : 기법을 배울 때는 방식 자체만을 모방하지말고
    목적을 파악하는 것이 습득에 이르는 지름길이다.

*WET (Write Every Tiem, Write EveryThing Twice)

DRY가 되어 있지 않은 코드에 대해 비꼬는 표현이다.

*OFOP (One Fact in One Place)

한 곳에는 하나의 사실
데이터베이스 논리 설계에서 테이블 설계의 핵심이 되는 원칙이다.

*OAOO (Once and Only Once)

한번만, 단 한번만
DRY와 유사한 의미


3. YAGNI You Are Not Going to Need It

*코드는 필요할 때 최소한으로!

*why_코드의 예측은 빗나간다.

시간이 지날수록 이렇게 사용하지도 않는 코드가 있는 것인지 영문을 알 수 없다. 오히려 방해물이 된다.

*코드는 지금 필요한 것만

우선 사용할 수 있는 데 가치를 주자.
범용성보다는 단순성이라는 가치에 기준을 두고 고른다.
단순한 방식이 사실 범용성이 더 높을 때가 많다.


4. PIE

Program Intently and Expressively
의도를 표현해서 프로그래밍하라

*코드의 의도를 전한다.

블로그에 글을 쓰듯이 명확한 의도
사람이 읽기 위한 것이기 때문

*why_코드가 유일한 실마리

코드는 소프트웨어 동작을 정확하고 완벽하게 알기 위한 유일한 실마리

  • 요구사항 정의서 : 어떤 기능을 원하는지가 적혀 있을 뿐
  • 기본 설계서 : 어떤 식의 소프트웨어로 요구사항을 실현할지 적혀있을 뿐
  • 상세 설계서 : 어떤 식의 구조로 소프트웨어를 작서할지에 관한 예정

코드와 가장 밀접하지만, 실시간으로 코드와 동기화되지 않는다.
결국 코드가 유일한 실마리

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

읽기 쉬움을 중시하자.
작성효율보다는 읽는 효율이 우선시된다.!! 읽기 쉽다면 나중에 실행 효율을 높이기는 간단하다.

다른 사람이 내 코드를 볼 때 이해가 잘 되도록 노력하자.

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

읽기 쉽고
오류가 없으며
품질이 좋은 코드와
테스트를 작성하려면 시간이 걸린다.

이는 단기적으로 손실로 보이지만, 두더지 잡기식 개발이 되지 않으므로
장기적으로 반드시 이익을 가져다 준다.

*주석을 작성한다.

주석으로 설명하지 않아도 되는 이해하기 쉬운 코드를 지향하면서,
표현할 수 없는 부분에는 주석을 활용하는 식으로
균형잡힌 코드를 작성하도록 하자.

*문학적 프로그래밍

literate programming
코드 자체를 문서화하는 기법
문서를 기술하기 위한 언어가 프로그래밍 언어와 결함되어 있다.
코드는 곧 문서이며, 문서는 곧 코드다.

groc


5. SLAP

Single Level of Abstraction Principle :: 추상화 수준의 통일

*코드 수준을 맞춘다.

고수준 추상화 개념과 저수준 추상화 개념을 분리해야한다.
상하 2계층이 아니라 기능의 복잡도에 따라 여러 계층으로 분리한다.
각 계층에서는 추상화 수준을 일치시킨다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function 고수준() { //수준 1의 목차
중수준1();
중수준2();
}

function 중수준1() { //수준2의 목차-1
저수준1();
저수준2();
}

function 저수준1() { //본문 내용
//처리
}

function 저수준2() { //본문 내용
//처리
}

function 중수준2() { //수준2의 목차-2
저수준3();
}

function 저수준3() { //본문 내용
//처리
}

*why_코드에 요약성과 열람성을 가져다준다

  • 함수의 일람 : 목차, 요약성을 지님
  • 분할된 함수 : 작은 코드 묶음, 열람성이 좋아짐.

*how_함수를 구조화한다.

함수를 구조화하자.
함수를 구조화하면 각 함수는 자신보다 한 단계 낮은 수준의 함수를 호출하는 처리가 중심이 된다.
다른 함수를 호출하는 코드로 구성된 함수 : 복합함수 (composed method)

복합함수

  • 최대한 작게 만든다.
  • 추상화 수준이 다른 함수를 호출하지 않도록 한다.

*SLAP의 적용범위

함수 뿐만 아니라 모듈 등에도 적용된다.

  • 개념을 저장할 저장소는 추상클래스와 해당 상속클래스가 된다.
    • 추상클래스 : 무엇인가 덜 구체화 된 것
    • 객체 : 상태와 행동을 가진 것
    • 클래스 : 객체를 만들기 위한 틀
    • 초기화 : 클래스를 이용하여 객체를 생성
  • 추상 클래스에 높은 수준의 개념을 갖게 하고
  • 상속 클래스에 낮은 수준의 개념을 갖게 한다.

*SLAP의 순서

글을 쓸때는
내용을 쓰는 것내용을 이해하기 쉽게 전하기 위한 구성을 생각하는 것을 별개의 작업으로 본다.

  • 구체적인 처리를 작성하는 작업
  • 추상화 수준을 일치시키는 작업은
    모드를 전환해서 별개의 작업으로 수행하도록 하자.
    그래야 작업이 쉬워지고 결과적으로 더 좋은 코드가 만들어진다.

6. OCP

Open-Closed Principle : 개방-폐쇠의 원칙

*코드의 변경은 파급시키지 않는다.

코드는 확장에 대해서 열려 있고
수정에 대해서 닫혀 있는
2가지 속성을 동시게 충족하도록 설계한다.

  • 확장에 열려있다. : 코드의 동작을 확장할 수 있다
  • 수정에 닫혀있다. : 코드의 동작을 확장하더라도 그 밖의 코드는 전혀 영향을 받지 않는다는 의미

*why_코드의 변경에 유연하게 대응한다.

변경에 대해 유연하게 대응할 수 있는 유연한 설계가 요구된다.

*OCP의 적용 범위

코드의 모든 부분에 OCP를 적용하는 것은 과한 방식이다.
코드의 단순함을 우지할 수 없다.

변경내용을 지나치게 예측하지 말아야 한다.
실제 변경이 발생하기를 기다리는 전략.
첫번째 변경을 감수하고, 두번째부터 OCP를 적용한다.
기본적으로 예측 가능한 부분에는 확장성 있게 작업한다.

*OCP의 구현과 설계

대표적인 기술 : 객체지향의 다향성

  • 다향성(polymorphism)은 특정 기능을 선언(설계)부분(=인터페이스)과 구현(동작)부분으로 분리한 후 구현부분을 다양한 방법으로 만들어 선택해서 사용할 수 있게 하는 기능.
  • 선언부분과 구현부분은 1:N의 다향성 관계가 형성
  • 다향성 선언부분: 인터페이스(interface)와 추상클래스(abstract class)
  • 다향성 구현부분: 클래스(class)

대표적인 디자인 패턴

  • strategy pattern
    • 교환 가능한 행동을 캡슐화하고 위임을 통해서 어떤 행동을 사용할지 결정한다.
    • 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리 시킨다.
    • 바뀌는 부분은 따로 뽑아서 캡슐화 시킨다.
  • Observer
    • 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의한다.
  • template method pattern
  • decorater pattern


참고링크
객체지향의 다향성 : http://webclub.tistory.com/406
strategy pattern : http://hyeonstorage.tistory.com/146