**[프로그래밍의 정석]**을 보고 메모한 부분을 정리했습니다.
목차
- KISS :: Keep It Simple, Stupid
- 오컴의 면도날
- DRY :: Don’t Repeat Yourself
- YAGNI :: You Aren’t Going to Need it
- PIE :: Program Intently and Expressively (의도를 표현해서 프로그래밍하라)
- SLAP :: Single Level of Abstraction Principle (추상화 수준의 통일)
- OCP :: Open-Closed Principle (개방-폐쇄의 원칙)
서론
1. KISS _Keep It Simple, Stupid
*코드는 단순하게 유지한다.
*why_아무생각 없이 수정하게 되면 코드는 무질서로 향한다.
함수의 경우 관심사 분리를 목표로 간결하게 유지한다.
- 단순한 코드는 읽기 쉽고 수정이 용이하다.
- 의사소통 유지비용을 절약할 수 있다.
*how_코드에 불필요한 것을 하지 않는다.
단순함을 프로그래밍의 나침반으로 삼자.
아래 상황을 경계하자.
- 새롭게 배운 기술을 사용하고 싶다.
- 장래의 필요에 대비하고 싶다.
지금 필요할게 아니면 지금 작성할 것이 아니다. - 멋대로 요구사항을 추가한다.
요구사항을 결정하는 쪽은 사용자다. 프로그래머가 요구사항을 결정해서는 안된다.케바케일듯
*Less is more 단순한 것이 더 아름답다.
지금 작성하는 코드가 정말로 필요한지를 항상 자문자답해야한다.
*오컴의 면도날
어떤 상황을 설명하는 데 필요 이상으로 많은 전제를 가정해서는 안된다는 사고방식.
= 뭔가에 관해 여러 가지 설명이 가능하다면 가장 단순한 방식이 옳다.
2. DRY
*코드 복사는 금물
- 로직 한 덩어리를 다른 부분에 복붙
- 같은 로직이 여러 군데로 흩어진다.
- 같은 조건을 다루는 제어문 블록이 여러군데 중복
- 같은 의미의 값(상수, 정수..)
*why_코드를 개선할 수 없다
- 코드를 읽는 작업이 어려워진다.
양적으로 많아지고 질적으로 복잡해진다. - 코드를 수정하는 작업이 어려워진다.
신중하게 수정하지 않으면 수정에 누락이 생길 위험성이 있다.
미세한 차이가 있다면 코드를 더욱 깊게 읽어야한다. - 테스트가 없다.
열심히 수정하더라도 테스트가 없는 상태에서는 새로운 오류가 발생할 위험이 커진다.
*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
코드 자체를 문서화하는 기법
문서를 기술하기 위한 언어가 프로그래밍 언어와 결함되어 있다.
코드는 곧 문서이며, 문서는 곧 코드다.
5. SLAP
Single Level of Abstraction Principle :: 추상화 수준의 통일
*코드 수준을 맞춘다.
고수준 추상화 개념과 저수준 추상화 개념을 분리해야한다.
상하 2계층이 아니라 기능의 복잡도에 따라 여러 계층으로 분리한다.
각 계층에서는 추상화 수준을 일치시킨다.
1 | function 고수준() { //수준 1의 목차 |
*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