Clean Code ¶
- CleanCode book
- CleanCoders
- 쩌네 이런데가 있네요. 안경끼고 손가락질 하는 분 엉클 밥 같으신데..? - 서지혜
- 쩌네 이런데가 있네요. 안경끼고 손가락질 하는 분 엉클 밥 같으신데..? - 서지혜
- Google Code Review System
- google coding style guide
- Martin Fowler의 refactoring home
- Express names in code: Bad vs Clean
- git 사용과 관련된 pro git이라는 책의 한국어 번역본. 상당히 자세히 나와 있다고 하네요
5월 11일 ¶
- Clean Code 읽은 부분에 대해 토론(Chap 01, Chap 09)
- Chapter 2 Meaningful Names - Naming Convention
- 클래스의 이름을 지을 때는 -info, -data와 같은 일반적인 이름을 쓰지 말라.
- Account를 만들면 되지 AccountInfo라는 클래스를 만들 필요는 없다. Account 클래스 내부에 들어가는 정보가 Info니까.
- -List 라는 식의 이름을 지을 때는 정말로 List의 API들을 지원할 때에만 -List라고 붙여주는것이 좋다. 이름을 저렇게 지으면 -List의 API들을 지원할 것 같은 느낌이 들기 때문에 아닐 경우에는 -s나 다른 방식으로 하는게 좋을 것.
- 아래와 같은 식으로 Account내부의 정보를 하나로 묶으면 AccountInfo 클래스와 getAccountInfo()등이 있을법하지 않은가? -> 저런 구조 자체가 잘못됐을 수 있다. getAccountInfo()와 같은 방법이 아니라 다른 방법으로 일을 시키는 모양이 더 낫다.
- 클래스의 이름을 지을 때는 -info, -data와 같은 일반적인 이름을 쓰지 말라.
- Chapter 2 Meaningful Names - Naming Convention
Class Account { private AccountInfo info; };
- Chapter 9 Unit Tests
- 문제를 들었을 때 테스트코드를 먼저 생각하는 습관을 들여야 할 것 같다. 문제를 해결하는 코드를 먼저 짜려고 하면 결국 테스트코드 작성이 아니라 직접 테스트를 하게 되는 듯 하다.
- 피드백을 빨리 받기 위해서 테스트를 실시. 피드백을 받고 고칠 때까지의 주기가 짧아야 함. 코드를 짜고 유닛테스트를 만드는 것도 안되는건 아님. 피드백을 바로 받을 수 있으면 됨.
- 코드를 깨끗하게 하고 싶으면 테스트 코드도 깨끗하게 유지해야 한다. 테스트 코드가 더러워지면 테스트를 잘 안하게 되니까 코드도 더러워지게 된다.
- 테스트 시에는 올바른 input이 제대로 들어오는지를 먼저 확인하고 나서 코드가 잘못되었는지 생각해볼 것.
- 실제로는 쓰지 않는데 테스트를 위한 메소드를 추가하게 되는 경우가 있을 수 있지 않은가? -> java의 경우는 reflection을 사용하면 메소드의 추가 없이 처리가 가능한 경우도 있지만 그것보다도 테스트용 framework(mockito 등)를 사용하는것이 좋다.
- BDD, Given/When/Then
- 문제를 들었을 때 테스트코드를 먼저 생각하는 습관을 들여야 할 것 같다. 문제를 해결하는 코드를 먼저 짜려고 하면 결국 테스트코드 작성이 아니라 직접 테스트를 하게 되는 듯 하다.
- gerrit 설치
- 참고 데모 동영상
- 버전관리가 필요한 이유를 깨닫는 어떤 사람
- gerrit install guide
- 위와는 좀 다른 참고 사이트 - 이쪽이 전체적인 흐름이나 아파치 설정 관련은 좀 더 보기 괜찮은 것 같다.
- Gerrit기동시에「** ERROR: GERRIT_SITE not set」
- 헐ㅋㅋㅋ 번역하니까 인스토루디레쿠토리로 나온닼ㅋㅋㅋ 전 그냥 환경변수 설정 해버렸습니다. 절대경로 쓰다가 베이스 디렉토리 한번 날려먹고 가능하면 피해범위 적도록 경로 이동해서 조작하거든요. - 서지혜
- 헐ㅋㅋㅋ 번역하니까 인스토루디레쿠토리로 나온닼ㅋㅋㅋ 전 그냥 환경변수 설정 해버렸습니다. 절대경로 쓰다가 베이스 디렉토리 한번 날려먹고 가능하면 피해범위 적도록 경로 이동해서 조작하거든요. - 서지혜
- 참고 데모 동영상
- next : git과 연동
- Git + Gerrit + Jenkins 전체 결합을 통해 코드 버그를 줄여보자
5월 18일 ¶
- 함수
- 플래그는 추하다
- guard clause를 쓰세요!
- 함수는 하나의 일을 하는게 좋다고 하는데 플래그를 쓴다는 것은 함수가 플래그의 값에 따라서 다른 값을 한다고 말하는 것이므로.
- 차라리 다른 일을 하는 함수를 여러개 만드는게 더 낫다.
- guard clause를 쓰세요!
- abstraction level
- String.append와 PathParser.render는 둘이 서로 문자열을 합치는 작업을 하더라도 직접적인 연산을 하는 것과 추상적인 연산을 하는 것의 차이로 서로 추상화 수준이 다르다고 할 수 있다.
- 추상화 수준이 서로 다른 코드가 섞여있으면 보기에도 좋지 않다.
- 추상화 레벨이 달라지는 것을 막기 위해서는 코드를 짧게 하고 메소드로 많이 나누면 한 코드 내에서 추상화 레벨이 달라지는 것을 막을 수 있다.
- String.append와 PathParser.render는 둘이 서로 문자열을 합치는 작업을 하더라도 직접적인 연산을 하는 것과 추상적인 연산을 하는 것의 차이로 서로 추상화 수준이 다르다고 할 수 있다.
- 함수 인자는 적을수록 좋다.
- 함수 인자가 많아지게 되면 사용자가 인자들에 대해서 이해를 하기 힘들다.
- 테스트 코드를 작성할 때 인자들의 조합 수에 따라 테스트 케이스가 늘어날 수 있기 때문에.
- 함수 인자가 많아지게 되면 사용자가 인자들에 대해서 이해를 하기 힘들다.
- 플래그는 추하다
- Error Handling
- 에러를 방지하거나, 처리하는 코드 때문에 함수의 본 임무를 파악하기 힘들게 되면 안됩니다.
- Consider using try-catch-finally instead of if statement.
- Don't return null.
- Returning null or undefined (Javascript)
var array = stringObject.match(/regexp/); // if there is no match, then the function returns null, if not returns array. if(!array){ // handle and return } array.forEach(/* handle found strings */) ...
- Returning emtpy object (Javascript)
var array = stringObject.match(/regexp/) || []; // if the function returns null, then substitute empty array. array.forEach(/* handle found strings */) /* You can handle empty array with "array.length === 0" statement in anywhere after array is set. */
- Returning null or undefined (Javascript)
- Don't pass null.
- 에러를 방지하거나, 처리하는 코드 때문에 함수의 본 임무를 파악하기 힘들게 되면 안됩니다.
후기 ¶
- 민관
- + : 코드 리팩토링을 해봐서 좋았다. 화이트보드에 적어가면서 읽어본 부분 공유하니까 정리된 느낌.
- - : 프로젝트 방식과 방향이 흐릿한 느낌이다.
- F : 시간을 컴팩트하게 진행하고 싶다. 늘어지는 경향이 있다.
- + : 코드 리팩토링을 해봐서 좋았다. 화이트보드에 적어가면서 읽어본 부분 공유하니까 정리된 느낌.
- 진경
- + : 리팩토링을 시도해보았다. 다른 사람의 코드를 리팩토링 할 수 있다는 생각을 하게 되었다.
- - : 본인의 코드를 리뷰받고 싶었는데 정리가 되지 않아 받지 못했다.
- F : 주중에도 스터디를! 온라인 협업 툴을 이용할 수 있다.
- + : 리팩토링을 시도해보았다. 다른 사람의 코드를 리팩토링 할 수 있다는 생각을 하게 되었다.
- 영주
- + : 책 얘기만 한게 아니라 책의 예제를 시도해봤다.
- - : 각자 예제를 리팩토링했다. 따로 논 느낌.
- 사실 그런 느낌이 들어도 결국 코드 짜는 부분은 따로 할 수밖에 없는 것 같으니 어쩔 수 없는 것 같기도 하지만요. - 서영주
- 사실 그런 느낌이 들어도 결국 코드 짜는 부분은 따로 할 수밖에 없는 것 같으니 어쩔 수 없는 것 같기도 하지만요. - 서영주
- F : 스터디를 제대로 하고 있는지 알고싶다. (멘토가 있었으면 좋겠다?)
- + : 책 얘기만 한게 아니라 책의 예제를 시도해봤다.
- 희정
- + : 처음 나올때 떨렸는데 많이 신경 써 줘서 좋았다.
- - : 배경지식이 부족한 듯 하다.
- F : 스터디중에 어떻게 진행해야 하나에 대한 얘기를 너무 많이 한다.
- + : 처음 나올때 떨렸는데 많이 신경 써 줘서 좋았다.
- 지혜
- + : 다른 사람들이 리팩토링 하는 것을 보았다. 새로운 사람 추가
- - : 리팩토링을 할 때 리팩토링에 대한 요구사항, 리팩토링을 멈출 수 있는 수준을 제시하지 못하였다.
- '이것'을 제시할 수가 있나?
- '이것'을 제시할 수가 있나?
- F : 스터디 첫날 정했던 각자의 목적과 목표(어디갔지?)를 통해 스터디가 제대로 진행되어 가고 있는지 체크할 수 있을것.
- 그러나 자신의 실력이 더 나음을 어떻게 비교할 수 있을까? 학습 곡선도 무시할 수 없다.
- 그러나 자신의 실력이 더 나음을 어떻게 비교할 수 있을까? 학습 곡선도 무시할 수 없다.
- + : 다른 사람들이 리팩토링 하는 것을 보았다. 새로운 사람 추가
5월 25일 ¶
- ajax (callback에 대한 이해를 위해)
- javascript를 이용한 비동기 http 요청.
- UI를 그리는 흐름(thread)과 http 요청에 대한 흐름(thread)이 따로 존재함.
- http 요청 쪽은 언제 작업이 끝날지 알 수 없음.
- callback 함수라는 것을 이용해서 작업이 끝났을 때 처리할 방법을 정할 수 있다.
- callback 함수라는 것을 이용해서 작업이 끝났을 때 처리할 방법을 정할 수 있다.
- javascript를 이용한 비동기 http 요청.
- 진경이 코드(CauBooks) 살펴보기
- javascript 소스 코드에서 한꺼번에 인자를 넘기는 방식.
- 로그인 성공, 실패에 따른 callback 함수를 한 번에 넘기고 있다.
- 현재는 callback 함수에 이름을 붙여서 인자에 넣고 있지만 주로 익명 함수를 쓰는 js의 특징이나 프로그래머가 직접 이름을 붙여서 관리를 해야 하는 등의 불편함을 고려하여 다른 방식으로 수정하고 싶다.
- 로그인 성공, 실패에 따른 callback 함수를 한 번에 넘기고 있다.
- 한꺼번에 { id:, password:, success:, fail: }을 하나의 객체로 만들어서 넘기는 방식.
- id, password와 success, fail은 관계가 별로 없는데 같이 묶어서 넘기면 나중에 login 내에서 각각의 파트를 또 뽑아내야 한다.
- 객체가 넘어가는 거니까 특정 property의 유무에 따라 에러를 일으킬 수 있다.
- id, password와 success, fail은 관계가 별로 없는데 같이 묶어서 넘기면 나중에 login 내에서 각각의 파트를 또 뽑아내야 한다.
- module.login(id, password).success(function() {...}).fail(function() {...})으로 수정할 경우.
- 각 callback 함수에 대한 의도가 보다 잘 드러남.
- 각 callback 함수에 대한 의도가 보다 잘 드러남.
- javascript 소스 코드에서 한꺼번에 인자를 넘기는 방식.
- 좋은 코드?
- 현재 CleanCode에서 좋은 코드로 너무 가독성만을 중시하고 있는 것은 아닌가.
- 읽을 사람의 수준을 고려하는 것도 필요하다. (너무 다 풀어 쓴 코드보다는 읽는 사람이 이해할 수 있을 정도의 난이도 + 효율적인 코드가 낫지 않은가)
- 읽을 사람의 수준을 고려하는 것도 필요하다. (너무 다 풀어 쓴 코드보다는 읽는 사람이 이해할 수 있을 정도의 난이도 + 효율적인 코드가 낫지 않은가)
- 현재 CleanCode에서 좋은 코드로 너무 가독성만을 중시하고 있는 것은 아닌가.
- 서지혜의 my-calculator 테스트 코드 리뷰
- spec에 지정되어 있지 않은 경우에 테스트 코드를 작성해야 하는가?
- spec에 지정되어 있지 않다는건 무슨 의미지?? - 서지혜
- 예를들면 입력이 들어왔을 때 A라는 출력이 나와야 한다고만 spec에 정의돼있으면 입력이 없을 때에 대한 테스트 코드는 무슨 기준으로 작성하느냐 또는 에러처리를 해야 하는가에 대한 기준을 말하는것 같습니다. - 서영주
- 아, 그런말 한 것 같네요. 이경우는 코드가 아니라 요구사항(아키텍처) 단계에서 정의가 필요한 일이네요. - 서지혜
- 실제 일하는데서는 어떤가요? 이런 부분에 대한 요구사항이 없을 경우에는 어떤식으로 처리를 하는지가 궁금합니다. 먼저 처리하고 어떻게 처리했다고 따로 보고하나요? 아니면 없으니까 이런걸 정의해줘야 한다고 건의를 하고 대답이 오면 그 때 처리를 하나요? - 서영주
- spec에 지정되어 있지 않다는건 무슨 의미지?? - 서지혜
- spec에 지정되어 있지 않은 경우에 테스트 코드를 작성해야 하는가?
- Ruby StyleGuide - 코딩 스타일 자체보다 왜 그런 스타일을 선택했는지에 대해 생각해 보는 것이 중요함.
회고 ¶
- 지혜
+ : 회사에서 짐을 나르다가 왔는데(이삿짐 나름.. 주말에.. 젠장), 오기를 잘 한 것 같다.
- : 원래 올 계획이 아니었기 때문에 필요한 노트북이나 책 등을 챙겨오지 못 했다.
- 서영주
+ : 무작정 클린 코드에 대해 이야기를 했었는데 좋은 코드에 대한 얘기를 하면서 클린 코드에 대해 다시 생각하게 됨.
- : 좋은 코드를 구해 오자고 했는데 하다 보니 생각보다 어려워서 못 찾아온 것에 대한 미안함.
- 진경
+ : 서영주가 코드에 대해 리뷰를 하고 생각을 적어 준 것. -> 누가 코드를 봐 줬으니 다음 주에 또 작업을 할 동기가 됨.
- : 스터디 시간의 경계선이 아직 뚜렷하지 않음.
f : - 줄이고 + 늘리게
- 박희정 <= 자기 코드 들고 오면 좋겠다
+ : 초반에 callback, ajax에 대해 따로 설명을 해 준 게 좋았음
- : 말하는 내용을 완전히 이해하기가 힘들다.
- 서민관
+ : 따로 준비 해 온 게 없었지만 그래도 다른 분들 덕분에 진행이 잘 되었다. 준비를 하지 않더라도 참가에 의미가 있다는 생각을 할 수 있게 되었다.
- : 시간 줄일 수 없을까? 책진행? 코드 진행? 진행을 어떤 식으로 해야 할지 아직도 매끄럽지 않은 느낌이 있다.
6월 8일 ¶
- 4장 코멘트
- CleanCoders 강의 맛보기.
- 에피소드 1은 1달러여서 싼 줄 알았는데 그 이후부턴 12달러...ㅠㅠ
- 지원금으로 구매하는게 좋겠음.
- 에피소드 1은 1달러여서 싼 줄 알았는데 그 이후부턴 12달러...ㅠㅠ
- SE titan 코드 리뷰
- 회식 - 7만원 지원받음
6월 22일 ¶
8월 24일 ¶
- 김남규, 박희정, 서민관, 서영주, 정진경
- Ch. 11 Systems
- Separate Constructing a System from Using It.
- Separate Constructing a System from Using It.
- 생성과 사용을 분리했을 시의 장점
- 객체 사용 코드는 대개 application 레벨인 경우가 많은데, 객체 생성 방법이 바뀌어도 사용 부분은 그대로 유지할 수 있다.
- 객체 생성시에 다양한 추가 작업들(proxy, lazy initialization 등)이 가능하다.
- 생성
- Factory Pattern
- Factory를 사용하기 때문에 복잡한 객체의 생성이나 객체의 실제 모양을 숨길 수 있다.
- application 단계에서 Factory를 통해서 직접 객체를 생성하기 때문에 해당 객체의 생성 순간을 application에서 통제 할 수 있다.
- Dependency Injection
- 객체의 책임을 깔끔하게 나눌 수 있다.
- 시스템의 구조가 복잡해 질 수 있다.
- Factory Pattern
- 횡단 관심사의 처리(AOP) : DB 접속, transaction, log 등 다양한 모듈들에서 동일하게 나타나는 작업들
- Java Proxies : 객체 생성 시에 proxy를 거치게 하는 방법을 통해 해당 객체의 메소드 호출시 다양한 부가 작업들(횡단 관심사)을 처리할 수 있다. 다만 사용이 복잡하고 사용시에도 아래의 방법들에 비해 제한이 좀 있다.
- EJB, Spring ... : 해당 framework에서 제공하는 다양한 방법들을 통해 xml, annotation 등의 간단한 설정으로 횡단 관심사에 관한 코드를 작성하지 않고도 해당 기능들을 자신의 프로그램에 넣을 수 있다.
- Java Proxies : 객체 생성 시에 proxy를 거치게 하는 방법을 통해 해당 객체의 메소드 호출시 다양한 부가 작업들(횡단 관심사)을 처리할 수 있다. 다만 사용이 복잡하고 사용시에도 아래의 방법들에 비해 제한이 좀 있다.
8월 31일 ¶
- 김남규, 박희정, 서민관, 서영주, 정진경
- Ch. 12 창발성
- 창발 현상
- 작은 부분을 보았을 때는 나타나지 않는 특성이 전체를 보았을 때는 나타나는 경우를 말한다.
- 코드의 성능 개선을 위한 부분적인 리팩토링이 이어지다 보면 어떤 패턴이 나타나는 경우를 예로 들 수 있다.
- 작은 부분을 보았을 때는 나타나지 않는 특성이 전체를 보았을 때는 나타나는 경우를 말한다.
- 인터페이스 분리 원칙 (ISP)
- 어떤 객체의 사용자에게 그 사용자한테 필요한 메소드만 있는 인터페이스를 제공하라.
- 어떤 객체의 사용자에게 그 사용자한테 필요한 메소드만 있는 인터페이스를 제공하라.
- proxy pattern in javascript
- 자바스크립트에서 지원하는 apply 함수와 arguments로 함수의 인자값을 받아올 수 있는 것을 이용해 외부의 라이브러리 사용 없이도 간단하게 proxy를 구현할 수 있다. jquery-aop 등의 외부 라이브러리도 있다.
- 자바스크립트에서 지원하는 apply 함수와 arguments로 함수의 인자값을 받아올 수 있는 것을 이용해 외부의 라이브러리 사용 없이도 간단하게 proxy를 구현할 수 있다. jquery-aop 등의 외부 라이브러리도 있다.
- 창발 현상
(function() { var proxied = console.log; console.log = function() { alert(arguments[0]); // 이렇게 apply의 앞 혹은 뒤로 실행되기를 원하는 기능을 호출한다. return proxied.apply(this, arguments); }; })();