시그마 삽질==six 시그마

Clean Code 요약 (로버트 마틴 밥아저씨) 본문

프로그래밍/Programming stuff

Clean Code 요약 (로버트 마틴 밥아저씨)

Ethan Matthew Hunt 2020. 9. 19. 23:30
Clean code(저자: 로버트C.마틴, 엉클밥 ) 구입하시길 강력 추천드립니다.

책 구입을 원하시는분은 요기를 클릭하시면 됩니다.

하단의 내용은 제가 예전에 읽었던 내용을 제 나름대로 요약한 것으로 저자의 의도와는 다를 수 있습니다

 

목차

 

1장 깨끗한 코드

 

코드가 존재하리라- 궁극적으로 코드는 요구사항을 표현하는 언어라는 사실을 명심하라

코드 품질을 측정하는 유일한  척도= 분당 내지르는 WTF 횟수

 

 

__ 태도

나쁜 코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 행동은 전문가 답지 못하다

 

 

 

__ 깨끗한 코드란?

 

우아하고 효율적인 코드 

의존성을 최대한 줄여야 유지보수가 쉬워짐

오류는 명백한 전략에 의거하여 철저히 처리한다

깨끗한 코드는 한가지를 제대로 한다. 

깨끗한 코드는 고치기 쉽다

가독성, 

중복이 없다.

 

객체지향 설계의 원칙

SRP(The Single Responsiblity Principle) :클래스나 모듈을 변경할 이유가 하나, 하나뿐이어야한다는 원칙이다.

OCP(The Open Close Principle): 클래스는 확장에는 열려있어야 하며 변경에 닫혀 있어야 한다.

LSP(The Liskov Substitution Principle)서브타입은 그것의 기반 타입에 대해 대체 가능해야한다.

DIP(The Dependency Inversion Principle): 추상화에 의존해야 하며, 구체화에 의존하면 안된다.

ISP(The Interface Segregation Principle): 클라이언트에 밀접하게 작게 쪼개진 인터페이스를 유지한다

 

객체지향 설계의 원칙에 입각해 의존성과 중복을 줄여서 재사용성이 좋고 유지보수 하기쉽고, 가독성이 뛰어난 효율적인 코드를 만드는것

 

 

 

2장 의미 있는 이름

 

의도를 분명히 밝혀라---> if 문속의  조건문을 의미가 있는 함수로 추출해라. 조건문을 캡슐화하라. 부정문은 긍정문보다 이해하기 약간 더 어렵다. 그러므로 첫 문장 if를 긍정으로 만들어 조건문을 반전한다.

그릇된 정보를 피하라---> 실제 list도 list로 이름붙여서 한정하지말고 s를 붙여라..

 

발음하기 쉬운 이름을 사용하라!!!!!

검색하기 쉬운 이름을 사용하라!!!!

 

 

 

3장 함수

작게 만들어라!--->함수를 만드느 첫째 규칙은 작겍 둘째 규칙은 더 작게다. 20줄도 길다

if,else,while 문에 들어가는 블록은 한줄이어야한다.

 

한 가지만 해라! --->함수는 한가지를 해야한다. 그 한가지만 해야한다.

__ 함수 내 섹션

함수 당 추상화 수준은 하나로!--->함수가 한가지 일만 하려면 함수내 모든 몬장의 추상화 수준이 동일해야한다. 한 함수내에  추상화 수준을 섞으면 코드를 읽는 사람이 헷갈린다.

함수는 서술적인 이름을 사용하라!

함수 인수----> 최선은 입력 인수가 없는 경우고 차선은 인수가 1개뿐인 경우다.

 이항 함수--->  assertEquals(expected, actual) 두개가 헷갈릴수 있음

 

부수 효과를 일으키지 마라!--->함수에서 한가지를 하겠다고 약속해놓고 남몰래 다른짓 하지 마라!

__ 출력 인수

 

__ Try/Catch 블록 뽑아내기 ---> try/catch는 추하다 그걸 의미있는 별도 함수로 뽑아내는게 좋다

 

반복하지 마라!---> 중복은 코드가 늘어날뿐만아니라 알고리즘이 변하면 여러곳 손봐야한다. 중복은 소프트웨어의 몯느 악의 근원이다. 그래서 관계형DB에서는 정규식이 나왔고 AOP, COP 는 중복 제거전략이다.

 

함수를 어떻게 짜죠? ---> 소프트웨어는 글짓기와 같다. 한번에 쭉은없다. 생성,수정삭제 반복해서 좋은코드나옴

 

 

 

4장 주석

주석은 나쁜 코드를 보완하지 못한다 ---> 주석은 필요악이다. 우리는 코드로 의도를 표현하지 못해서 실패를 만회하기 위해 주석을 사용한다.

코드로 의도를 표현하라! ----> //직원에게 복지 혜택을 받을 자격이 있는지 검사한다.  if((employee.flags & HOURLY_FLAG) && (employee.age>65))  ------> if(employee.isEligibleForFullBenefits())

좋은 주석

__ 법적인 주석

__ 정보를 제공하는 주석 (추상 메서드가 반환할 값을 설명한다)

__ 결과를 경고하는 주석

__ TODO 주석

__ 중요성을 강조하는 주석

__ 공개 API에서 Javadocs

 

 

 

5장 형식 맞추기

 

 

적절한 행 길이를 유지하라

__ 신문 기사처럼 작성하라

__ 개념은 빈 행으로 분리하라 !!!!

__ 세로 밀집도

__ 수직 거리----> 종속함수. 한 함수가 다른 함수를 호출한다면 두 함수는 세로롤 가까이 배치한다. 또한 가능하다면 호출하는 함수를 호출되는 함수보다 먼저 배치한다.

 

 

 

6장 객체와 자료 구조

자료 추상화

자료/객체 비대칭 --->  자료구조: 자료공개(public 필드), 기능x / 객체:자료숨김(private필드), 기능공개

 

절차적인 코드는 새로운 자료 구조를 추가하기 어렵다. 그러려면 모든 함수를 고쳐야한다 객체 지향 코드는 새로운 함수를 추가하기 어렵다. 그러려면 모든 클래스를 고쳐야한다.

다시말해, 객체 지향 코드에서 어려운 변경은 절차적인 코드에서 쉬우며, 절차적인 코드에서 어려운 변경은 객체지향 코드에서 쉽다.

 

 

 

디미터 법칙

디미터의 법칙은 모듈은 자신이 조작하는 객체의 속사정을 몰라야한다는 법칙이다.

디미터의 법칙은 클래스의 C의 메서드f는 다음과 같은 객체의 메소드만 호출해아한다

-클래스C

-f가 생성한 객체

-f 인수로 넘어오느 객체

-C 인스턴스 변수에 저장된 객체'

하지만 위 객체에서 허용된 메서드가 반환하는 개체의 메서드는 호출하면 안된다.다시말해 낮선 사람은 경계하고 친구랑만 놀라는 의미다.

__ 기차 충돌

 

 

 

7장 오류 처리

오류 코드보다 예외를 사용하라--->오류가 발생하면 예외를 던지는 편이 낫다.

Try-Catch-Finally 문부터 작성하라

미확인unchecked 예외를 사용하라-throws 경로에 위치하는 모든 함수가 최하함수에서 던지는 예외를 알아야되므로 캡슐화가 깨진다.

예외에 의미를 제공하라

호출자를 고려해 예외 클래스를 정의하라-->오류가 발생한 취치 또는 오류가 발생한 컴포넌트, 유형으로도 분류가 가능하다. 외부 api를 사용할때 예외처리는 wrapper클래스로 감싸기 기법이 최선이다. 외부 Api를 감싸면 외부 라이브러리와 프로그램 사이에 의존성이 크게 줄어든다.

정상 흐름을 정의하라

null을 반환하지 마라--> 메서드에서 null을 반환하고픈 유혹이 든다면 그대신 예외를 던지거나 특수 사례 객체를 반환한다. Collections.emptyList()

null을 전달하지 마라

 

 

 

 

8장 경계

외부 코드 사용하기

Map sensors= new HashMap();

Sensor s =(Sensor)sensors.get(sensorId);

 

위대신 아래 제네릭스 사용

Map<String,Sensor> sensors = new HashMap<Sensor>();

Sensor s= sensors.get(sensorId);

 

 

9장 단위 테스트

TDD 법칙 세 가지

깨끗한 테스트 코드 유지하기 ---> 테스트 코드가 지저분할수록 변경하기 어려워진다. 테스트코드는 실제코드 못지않게 중요하다.

@Test

public void xxx(){

todoHot(); <---코드짜듯이 의미있는 메소드를 사용해볼것

}

 

 

F.I.R.S.T.

fast, Independent,Repeatable, Self-validating, Timely

 

 

10장 클래스

클래스 체계

__ 캡슐화

클래스는 작아야 한다!----> 클래스의 이름은 해당 클래스 책임을 기술해야한다. 실제로 작명은 클래스 크기를 줄이는 첫번째 관문이다.

 

__ 단일 책임 원칙--> 클래스나 모듈을 변경할 이유가 하나, 단 하나뿐이어야 한다는 원칙이다.

작은 클래스가 많은 시스템이든 큰 클래스가 몇 개뿐인 시스템이든 돌아가는 부품은 그 수가 비슷하다. 그럼 클래스가 여러개 많이생기는거에 걱정하는데 도구상자를 작은 서랍을 많이 두고 기능과 이름이 명확한 컴포넌트로 나눠넣고 싶나 아니면 큰 서랍 몇개를 두고 모두를 던져 넣고 싶은가. 큰 클래스가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다

 

 

__ 응집도Cohesion

클래스는 인스턴스 변수 수가 작아야한다.---> 응집도가 높다는 말은 클래스에 속한 메서드와 변수가 서로 의존하며 논리적인 단위로 묶인다는 의미다. 일반적으로 메서드가 자신이 가지고 있는 변수를 더 많이 사용할수록 메서드와 클래스는 응집도가 더 높다.   모든 인스턴스 변수를 메서드마다 사용하는 클래스는 응집도가 가장 높다. 함수를 작게, 매개변수 목록을 짧게라는 전략을 따르다보면 때때로 몇몇 메소드만이 사용하는 인스턴스 변수가 아주 많아진다. 이는 십중팔구 새로운 클래스로 쪼개야 한다는 신호다.

 

__ 응집도를 유지하면 작은 클래스 여럿이 나온다---> 몇몇 함수가 몇몇 변수만 사용한다면 독자적인 클래스로 분리해도 되지않는가? 당연하다. 클래스가 응집력을 잃으면 쪼개라. 큰함수를 작은 함수 여럿으로 쪼개다 보면 종종 작은클래스 여럿으로 쪼갤 기회가 생긴다.

 

변경하기 쉬운 클래스--->

public class Sql{

public sql(String table, Column[] colums)

public String create();

public String insert(Object[] fields)

public String selectAll()

...

}

<---SRP 위반... 한개한개 수정할때마다 Sql클래스 손대야함.책임분리가 안됨.

하단과 같이하면 SRP 지켜지고 OCP도 됨. 확장에 개방적, 수정에 폐쇄적

 

 

abstract public class Sql{

public sql(String table Colum[] columns)

abstract public String generate();

};

 

public class CreateSql extends Sql{

public CreateSql(String table, Column[] columns);

@Override public String generate();

}

 

public class SelectSql extends Sql{

public SelectSql(String table, Column[] columns);

@Override public String generate();

}

 

__ 변경으로부터 격리--->

 

 

DIP 클래스가 상세한 구현이 아니라 추상화에 의존해야한다. 

 

 

G18 부적절한 static함수.

결정적으로 Math.max 메서드를 재정의 할 가능성으 거의 전혀없다. 반드시 static 함수로 정의해야겠다면 재정의할 가능성은 없는지 꼼꼼히 다져본다.

 

G35 설정정보는 최상위단계에 둬라

 

다중 쓰레드 환경에서 안전하지 않은 클래스

SimpleDateFormat

데이터베이스 연결

java.util 컨테이너 클래스

servlet

 

 

Comments