Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

코드리뷰 짝 매칭 프로그램 구현기

1,708 views

Published on

Nodejs Program to join a team of six randomly paired with code review

Published in: Software

코드리뷰 짝 매칭 프로그램 구현기

  1. 1. 코드리뷰 짝 매칭 프로그램 구현기 2014-12-09 김 용 훈
  2. 2. 오늘 얘기 할 주제는? • Node.js에 대해선 다루지 않습니다. • 이걸 왜 만들었을까요? • 구현시 어려웠던 점. 느꼈던 점.
  3. 3. 이걸 왜 만들었을까요? • 현재 팀장포함 총 팀원수 7명 • 2개 프로젝트에서 코드리뷰 사항을 위키로 정리하여 공유 => 잘 안됨 • 코드리뷰 활성화를 위해 이 프로그램을 먼저 만들고 공유 => 유지보수부터 내 짝과 코드리뷰를 한번 해보자!
  4. 4. 이걸 왜 만들었을까요? • 코드리뷰 짝의 역할 정의 - 짝의 요청이 있으면 같이 설계참여. 커밋 전 코드리뷰(필수) - 정기배포시 시간적여유가 있으면 같이 테스트(옵션) • 코드리뷰 짝 매칭시 규칙 - 팀장제외 총 6명이 일대일로 매칭되어 총 3개의 짝 만듦 - 짝은 1주단위로 매주 금요일마다 바뀜 - 짝은 본인을 제외한 나머지 5명 중 랜덤으로 결정 단, 지난주에 짝이 된 사람과는 다시 짝이 되지 않음
  5. 5. 구현시 어려웠던 점. 느꼈던 점. • 처음에 했던 생각! “코드리뷰 짝 매칭 결과만 웹페이지 하나로 보여주면 될 것 같은데… Java + Spring을 써야할까…” => 그래서 간단하게 자바스크립트만으로 서버어플리케이션을 만들 수 있는 Node.js 선택
  6. 6. 구현시 어려웠던 점. 느꼈던 점. Node.js 기본개념 + 트위터백업예제/Express 필요한 부분 학습
  7. 7. 구현시 어려웠던 점. 느꼈던 점. [사용자 시나리오] 1. HTTP로 해당 URL 요청 2. Node.js 서버 Express가 처리 할 Controller 찾음 3. 비지니스로직 처리 후 결과를 EJS에게 보냄 4. 사용자는 EJS가 랜더링한 결과를 브라우져에서 봄 5. node-schedule이 백단에서 주기적으로 코드리뷰 결과데이터 넣음
  8. 8. 구현시 어려웠던 점. 느꼈던 점. http://bluepoet1004.cafe24.com:4000/users
  9. 9. 구현시 어려웠던 점. 느꼈던 점. • 어려웠던 점! 비동기 I/O => Node.js는 이벤트루프기반의 비동기 I/O로 실행됨 이미지 출처 : http://www.techthali.org/node-js-asynchronous-non-blocking-events-callbacks/
  10. 10. 구현시 어려웠던 점. 느꼈던 점. • 어려웠던 점! 비동기 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. 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. 12. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “알고리즘”은 중요하다! “결국, Node.js와 그 안에서 쓰이는 기본/확장모듈은 내가 만들고자 하는 서비스를 빠르게 구현해주는 장식자(Decorator)의 역할인 것 같다….”
  13. 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. 14. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! “만들기에 바빠, 테스트코드 만드는 건 처음에 생각하지도 못함. 하지만… 다 만들고 웹페이지 결과도 봤지만 왠지모를 이 찜찜함…”
  15. 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. 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. 17. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! - Node.js Test Framework인 “Mocha”와 Node.js 내장 “assert 모듈”로 유닛테스트 작성
  18. 18. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! - BDD(behavior-driven development)로 작성된 유닛테스트코드를 통해 “내가 만든 코드에 대한 검증 및 추후 리팩토링에 대한 자신감” 얻음!
  19. 19. • 소스코드/프로젝트설명 보기 https://github.com/bluepoet/CodeReviewMatchingPair
  20. 20.

×