이걸 왜 만들었을까요?
• 현재 팀장포함 총 팀원수 7명
• 2개 프로젝트에서 코드리뷰 사항을 위키로 정리하여 공유
=> 잘 안됨
• 코드리뷰 활성화를 위해 이 프로그램을 먼저 만들고 공유
=> 유지보수부터 내 짝과 코드리뷰를 한번 해보자!
4.
이걸 왜 만들었을까요?
• 코드리뷰 짝의 역할 정의
- 짝의 요청이 있으면 같이 설계참여. 커밋 전 코드리뷰(필수)
- 정기배포시 시간적여유가 있으면 같이 테스트(옵션)
• 코드리뷰 짝 매칭시 규칙
- 팀장제외 총 6명이 일대일로 매칭되어 총 3개의 짝 만듦
- 짝은 1주단위로 매주 금요일마다 바뀜
- 짝은 본인을 제외한 나머지 5명 중 랜덤으로 결정
단, 지난주에 짝이 된 사람과는 다시 짝이 되지 않음
5.
구현시 어려웠던 점.느꼈던 점.
• 처음에 했던 생각!
“코드리뷰 짝 매칭 결과만 웹페이지 하나로
보여주면 될 것 같은데…
Java + Spring을 써야할까…”
=> 그래서 간단하게 자바스크립트만으로
서버어플리케이션을 만들 수 있는 Node.js 선택
6.
구현시 어려웠던 점.느꼈던 점.
Node.js 기본개념 + 트위터백업예제/Express 필요한 부분 학습
7.
구현시 어려웠던 점.느꼈던 점.
[사용자 시나리오]
1. HTTP로 해당 URL 요청
2. Node.js 서버 Express가
처리 할 Controller 찾음
3. 비지니스로직 처리 후
결과를 EJS에게 보냄
4. 사용자는 EJS가 랜더링한
결과를 브라우져에서 봄
5. node-schedule이
백단에서 주기적으로
코드리뷰 결과데이터 넣음
구현시 어려웠던 점.느꼈던 점.
• 어려웠던 점! 비동기 I/O
client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date,
INTERVAL 7 DAY) > NOW() AND create_date < NOW();select * from member order by
id', function(err, rows, fields) {
ㅗㅗㅗ소
if(err) {
throw err;
}
res.render('userList', {
users: rows[1],
prevUsers: rows[0],
title: 'Listing Developmemt Team CodeReview Matching Result'
});
});
비동기 I/O를 사용해 콜백함수를 전달하고, DB에서 조회가 끝났다는
이벤트가 발생하면 콜백함수를 처리한다는 걸 이해못함!
11.
구현시 어려웠던 점.느꼈던 점.
• 어려웠던 점! 비동기 I/O
client.query('SELECT * FROM member', function(err, results, fields) {
client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date, INTERVAL 7
DAY) > NOW() AND create_date < NOW();select * from member order by id', function(err, rows, fields) {
ㅗㅗㅗ소
if(err) {
throw err;
}
console.log('results ' + results[0].name);
res.render('userList', {
users: rows[1],
prevUsers: rows[0],
title: 'Listing Developmemt Team CodeReview Matching Result'
});
});
});
코드리뷰 매칭결과를 가져오는 콜백함수(클로저) 안에서 멤버를 조회
하는 콜백함수의 파라미터인 results(외부변수)를 참조할 수 있음!
12.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “알고리즘”은 중요하다!
“결국, Node.js와 그 안에서 쓰이는 기본/확장모듈은
내가 만들고자 하는 서비스를 빠르게 구현해주는
장식자(Decorator)의 역할인 것 같다….”
13.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “알고리즘”은 중요하다!
나의 코드리뷰짝 번호를 찾아주는
getRandomNumber(selectedNumber);
함수가 이 프로그램의 핵심!
손으로 구현하기 전엔 간단할 것 같았다..
하지만.. 막상 구현을 시작하니...
생각처럼 쉽지 않았고, 시간이 오래 걸림.
역시 “백문이 불여일타!”
getRandomNumber: function(selectedNumber) {
ㅗㅗㅗ소
var me = this;
var randomNumbers = [1,2,3,4,5,6];
randomNumbers.splice(randomNumbers.indexOf(selectedNumber), 1);
var prevPairNumber = me.prevPair.get(selectedNumber);
if(prevPairNumber !== undefined) {
randomNumbers.splice(randomNumbers.indexOf(prevPairNumber), 1);
}
for(var i=0; i<me.leftNumbers.length; i++) {
if(randomNumbers.indexOf(me.leftNumbers[i]) == -1) {
continue;
}
randomNumbers.splice(randomNumbers.indexOf(me.leftNumbers[i]), 1);
}
if(randomNumbers.length == 3) {
var deleteNumber = randomNumbers.slice(0);
for(var i=0; i<randomNumbers.length; i++) {
if(me.prevPair.get(randomNumbers[i]) !== undefined) {
var key = randomNumbers[i];
var value = me.prevPair.get(randomNumbers[i]);
deleteNumber.splice(deleteNumber.indexOf(key), 1);
deleteNumber.splice(deleteNumber.indexOf(value), 1);
break;
}
}
randomNumbers.splice(randomNumbers.indexOf(deleteNumber[0]), 1);
}
var randomNumbersCnt = randomNumbers.length;
var randomNumberIndex = Math.floor(Math.random() * (randomNumbersCnt -
1 + 1)) + 1;
return randomNumbers[randomNumberIndex-1];
},
14.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “테스트코드”는 꼭 작성하자!
“만들기에 바빠, 테스트코드 만드는 건 처음에
생각하지도 못함.
하지만…
다 만들고 웹페이지 결과도 봤지만 왠지모를 이 찜찜함…”
15.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “테스트코드”는 꼭 작성하자!
test/codeReviewPairLogicTest.js
ㅗㅗㅗ소
var assert = require('assert');
var pair = require('../pair');
var Map = require('./map');
before(function() {
pair.init();
pair.prevPair = new Map();
pair.result = new Map();
pair.prevPair.put(1, 5);
pair.prevPair.put(2, 6);
pair.prevPair.put(3, 4);
});
describe('[CodeReviewMatchingPair]PairLogicConfirm Test Suite', function() {
describe('CodeReviewPair Result Confirm', function() {
it('result count is 3, the key and value of the map is not the same', function() {
pair.fakeExtractPrevMembers();
assert.equal(pair.result.size(), 3);
var keys = pair.result.keys();
for(var i=0; i< keys.length; i++) {
assert.notEqual(keys[i] != pair.result.get(keys[i]), false);
}
});
});
});
16.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “테스트코드”는 꼭 작성하자!
“done()함수” 전달로 “비동기테스트” 가능! test/dbDataConfirmTest.js
ㅗㅗㅗ소
var assert = require('assert');
var db = require('./db');
var repo = require('../repository');
before(function() {
repo.getMembers();
});
describe('[CodeReviewMatchingPair]DbDataConfirmTest Test Suite', function() {
describe('Total Member Count : Direct Query', function() {
it('All Member is six', function(done) {
db.query('SELECT * FROM member', function(err, rows, fields) {
if(err) {
throw err;
}
assert.equal(rows.length, 6);
done();
});
});
});
describe('CodeReview Member Data Confirm', function() {
it('CodeReview Member Data Confirm', function(done) {
db.query('SELECT first_id, after_id FROM member_match_list where DATE_ADD(create_date, INTERVAL 7 DAY) > NOW() AND create_date < NOW()', function(err, rows, fields) {
if(err) {
throw err;
}
assert.equal(rows.length, 3);
for(var i=0; i< rows.length; i++) {
assert.notEqual(rows[i].first_id != rows[i].after_i, false);
}
done();
});
});
});
describe('Total Member Count : Other Module Called', function() {
it('All Member is six', function() {
assert.equal(repo.result.length, 6);
});
});
});
17.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “테스트코드”는 꼭 작성하자!
- Node.js Test Framework인 “Mocha”와
Node.js 내장 “assert 모듈”로 유닛테스트 작성
18.
구현시 어려웠던 점.느꼈던 점.
• 느꼈던 점! “테스트코드”는 꼭 작성하자!
- BDD(behavior-driven development)로 작성된
유닛테스트코드를 통해 “내가 만든 코드에 대한
검증 및 추후 리팩토링에 대한 자신감” 얻음!
19.
• 소스코드/프로젝트설명 보기
https://github.com/bluepoet/CodeReviewMatchingPair