3. 오마이랩 기술 팀 소개
• CTO 포함 프로그래머 4인
• 시니어 2인/ 주니어 2인(신입 1인)
• 글로벌 Multitenant 호텔 상품 관리 서비스 개발 중
• Multitenant 서비스 개발 경험자 없음
• 제품 관리자(Product Manager) 없음
• 디자이너 없음
• 거대 경쟁사들
• 경영진의 빠른 출시 요구
• Startup이 아님
7. Visual Studio
• 통합 개발 환경
• 코딩
• 버전 관리
• 테스팅 도구
• 디버거
• 1997~
• Visual Studio Team Services 통합
• Microsoft Azure 통합
8. Visual Studio Team Services
• 통합 소프트웨어 개발 생명주기 도구
• Code
• Git
• Pull Requests
• Work
• Boards
• Queries
• Build and Release
• Test
• Wiki
• Test & Feedback
9. Office 365
• Exchange, Outlook, Excel, PowerPoint, OneNote
• Microsoft Teams
• Slack vs Teams
• Office Lens
• 화이트보드 촬영
• Planner
10. Microsoft Teams
• 협업 소통 도구
• Slack vs Teams
• Slack의 높은 마감 품질
• Teams의 다양한 기능
• 채팅/ 영상 통화/ 파일 저장소/ 위키
• 각종 서비스 통합
• Office 365 제품군
• VSTS 통합
18. 중/ 장기 일정 계획
• 소프트웨어 개발 일정 계획은 난제
• 아이디어는 쉽고
• 코드는 어려움
• 프로그래머 개인의 능력은 전문적이고 생산성 격차가 매우 큼
• 대부분의 비즈니스 결정권자들은 소프트웨어를 이해하지 못 함
• 게다가 대부분의 기술자들은 결정권자들을 잘 설득하지 못 함
• 비즈니스는 시스템 개발 일정을 필요
• 시장 흐름 및 투자 계획
• 제품 홍보와 영업
19. 사용자 스토리 개발
• 사용자 스토리
• 사용자 입장에서의 기능
• 소프트웨어 가치 단위
• 사용자 스토리 개발 반복
• 사용자 스토리 작성
• 세부 설계
• 작업항목 도출
• 작업항목 진행 반복
• 피드백
• 사용자 스토리 평가
20. 사용자 스토리 작성
• 최우선 고객 가치 선택
• 경쟁 제품 벤치마크
• 언어 선택
• Ubiquitous Language
• 명사 + 동사
• 인격/ 기능/ 가치
As a <role>
I can <capability>,
so that <receive benefit>
21. 세부 설계
• 도메인 모델
• Ubiquitous Language
• 도메인 모델은 데이터베이스가 아니다.
• 데이터베이스는 도메인 모델의 상태를 영속시키는 도구
• 동사는 명사만큼 중요
• No Silver Bullet
• 확장성, 반응성, 복원성, 일관성, …
• 다양한 가치와 위험을 교차 평가해 합리적으로 결정
• 화이트보드를 이용해 논의 후 코드로 표현
• 코드와 가장 일관된 설계는 코드 자신
28. 코딩
• 작업항목 소스코드 분기 생성
• 짝 프로그래밍
• 코드 작성과 테스트
• 1회 이상 커밋
• GitHub Flow와 유사한 흐름
• https://guides.github.com/introduction/flow/
• 배치와 master 분기 병합 순서가 다름
29. 작업항목 소스코드 분기 생성
• 작업항목을 통해 분기 생성
[work item id]-[kebab-case-description]
388-unmapped-room-rates-api
422-replace-old-language
• 작업항목과 코드 연결
• 분기
• 커밋
• Pull Requests
• 빌드/ 배치
• 테스트
30. 짝 프로그래밍
• 실시간 코드 리뷰
• 코드 검증
• 지식 공유
• 상향 평준화 촉진
• 기술 조직의 복원성 향상
32. 코드 작성과 테스트
• 또는 테스트와 코드 작성
테스트 주도 개발(Test-Driven Development)
• 테스트는 크고 작은 요구사항을 표현
자가 검증 요구사항
• 기대된 동작 구현이 최우선
테스트가 기대된 동작 여부를 판단
33. 리팩터링(re factoring)
• 기능(논리, 데이터, 공용 인터페이스, …)이 아닌 코드 구조를 변경
• 현재의 코드는 미래의 코드에 영향을 미침
• 과거의 코드는 현재의 코드에 영향을 미침
• 한 번 쓰인 코드는 반드시 여러 번 읽힘
• 같은 동작을 기준으로 코드는 적을 수록 좋음
• 짧은 코드의 의미가 아님
• 불필요한 코드를 유지하는 비용은 낭비
• 리팩터링은 테스트 케이스의 검증에 기반
*Beck design rules(https://martinfowler.com/bliki/BeckDesignRules.html)
34. 커밋
• 소프트웨어의 가장 중요한 지식 기반
• 하나의 작업항목은 하나 이상의 커밋을 가짐
• 과도하지 않은 범위 내에서 작은 크기를 지향
• 설명력 있는 커밋 메시지
• 팀에 대한 배려
35. 커밋 메시지
• 변경 사항을 요약
• 코드로 표현하기 어려운 내용을 기재
• 공유된 작성 규칙
https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
https://justhackem.wordpress.com/2018/01/30/writing-git-commit-messages-using-vscode/
• 작업항목 연결
38. 커밋 메시지 사례 #1 – 한 줄 설명
Channel 연결 명령 API를 추가한다
work items: #175
39. 커밋 메시지 사례 #2 – 제목/ 본문
Channel Connector RoomRate 목록 API 추가
1. 헤더에 있는 사용자 인증정보 검사
2. 사용자 정보로 호텔의 RoomRate 목록 리턴
work items: #373
40. 커밋 메시지 사례 #3 – 작업 내용과 목적
라이프 사이클 메서드를 DidUpdate로 변경한다
- ComponentDidMount: 첫 렌더시에만 호출된다
- ComponentDidUpdate: props가 업데이트 된 후 호출된다
현재 form에서 채널 선택 필드의 변화를 지속적으로 감지하여 변화가 발생할
때 마다 props를 업데이트 하고 있다.
unmapped room rate 선택 필드는 채널 선택 필드에서 선택된 채널 id로
get 요청을 보내고 있기 때문에 채널 선택에 변화가 생길 때 마다 get 요청을
보내야 한다. 따라서 DidMount보다 DidUpdate가 더 적절하다.
수정한 코드에서는 DidUpdate에서는 업데이트 전 props와
업데이트 후 props를 비교하여 두 값이 다를 때만 get요청을 보낸다.
work items: #411
41. 커밋 메시지 사례 #4 – 미해결 문제 기록
MapRoomRateToChannel 명령에 누락된 속성을 채운다
Service Facade가 Channel Management 도메인 모델에 MapRoomRateToChannel
명령을 전송할 때 Channel Room Rate의 Description 정보들을 채운다.
추가된 논리는 수동으로 테스트 되었으며 실패하는 기존 단위 테스트
케이스는 DemoDay-2를 준비하기 위해 우선 비활성화 한다. 다음 설계 무결성
이슈 고려와 함께 DemoDay-2 이후 Task #415 에서 복구될 계획이다.
* 설계 무결성 이슈
MapRoomRateToChannel 명령을 도메인 모델에 보내기 위해 Channel Room Rate
목록을 조회해 클라이언트가 보낸 정보에 포함되지 않은 정보를 채운다. 이
과정에서 명령의 잘못된 상태들을 검증하게 되는데 이것은 도메인 모델
논리로 볼 수 있다. 즉, Service Facade가 Channel Management 도메인 논리를
포함하는 구조로 원래의 주어진 책임을 벗어난다. 만약 이 책임을
Channel Management 도메인 API로 옮기려면 Channel Management는
Service Facade 요청에 포함된 정보로만 구성된 중간 단계의 명령 메시지를
정의해 Service Facade에 제공해야 한다. 두 선택지 중 빠르게 구현할 수
있는 전자를 우선 취하지만 충분한 고민 후 설계 변경을 고려해야 한다.
work items: #413
57. 기능 테스팅(Functional Testing)
Apps
Lease ContainerEvent Hub
Dev/ Prod Resource Group
Functional Test Cases
Azure
CI/ CD Pipelines
Azure Storage Emulator
Visual Studio
IIS Express
SQL Server Express
Apps Lease Container
Event Hub
Local Resource Group
AzureLocalMachine
Local Visual Studio
71. 팀원 피드백 #1(시니어)
TDD와 DDD 기반에 Agile한 방식으로 4명의
멤버가 상호 소통하며 작업
아직 기획자/ 디자이너/ PMO/ QA/ SA 등
존재하지 않아 멤버마다 사고의 유연성이 필요
72. 팀원 피드백 #2(주니어)
• 이전 회사에서 인수인계 받은 코드에서 하나의 단어를 놓고 코드마다 다르게 사용해서 결과 값이
말도 안되게 나와 고생
• 단어에 대한 정의가 정확하다 보니 코드에서도 한눈에 알 수 있고, 어떤 것을 이해하지 못했는지
정확하게 파악할 수 있어서 질문자와 답변자 사이의 오해가 크게 줄어드는 효과가 발생
Ubiquitous Language
• 문법 검사 정도에서 끝나지 않는 코드 리뷰
• 개발자 모두가 코드 리뷰에 참여 하기 때문에 리뷰 하는 사람들이 코드의 의미를 정확하게 알 수
있도록 코드 하나 하나 신경 써서 작성하게 되는 효과가 발생하는 것을 경험 중
코드 리뷰
73. 팀원 피드백 #3-1(신입 나부랭이-명확한 프로세스)
유저 스토리 도출 ->
워크 아이템 등록/ 할당 ->
코딩 -> 코드리뷰 -> 병합
작업 프로세스가
명확하기 때문에 지금
하는 일이 끝나면 뭘
해야 하는 지 알고 있다
그래서 뭘 할지 잘 몰라
안절부절 하고 있을
일이 별로 없다
74. 팀원 피드백 #3-2(신입 나부랭이-코드 리뷰)
읽는 사람을 배려하기 위해 들이는 노력이 스스로에게도, 코드의
품질에도 긍정적인 영향을 준다는 것을 느낌
CTO가 매의 눈이라 코드 사이에 낀 먼지도 볼 것 같아, 커밋 하나 하나에
훨씬 신중
별도 요청 사항(“API에 식빵도 넣어줘!” 같은…?)도 코드 리뷰로 확인하기
때문에 커뮤니케이션 미스로 인한 master 브랜치 오염을 차단하는 효과
75. 팀원 피드백 #3-3
신입 나부랭이
통합 툴 사용
입사 전에는 Slack, GitHub, GitHub Project,
Google Docs, Hangout를 사용
‘스위칭 리소스’라는 고급진 표현이 쓰이는데,
이거 켰다 저거 켰다 하는 게 정말 귀찮았음
다른 도구로 넘어갈 때 마다 사고가 초기화
되어 뭘 하려고 했는지 한 번 더 생각함
지금은 VSTS 위에서 모든 것이 해결되기
때문에 너무 편하고 사고 정지 횟수 감소
이 약은 먹어봐야 앎
기능 테스팅은 기본적으로 빌드 및 배포 파이프라인에서 Azure 인프라에 배포 후 구동되는 코드를 대상으로 수행된다.
프로그래머는 빠른 피드백을 얻기 위해 작업 환경에서 기능 테스트 케이스를 실행한다.
로컬 기능 테스팅 시 응용프로그램 인스턴스는 Visual Studio와 IIS Express를 이용해 구동한다.
로컬 기능 테스팅 시 관계형 데이터베이스는 SQL Server Express를 이용해 구동한다.
로컬 기능 테스팅 시 저장소 계정은 Azure Storage Emulator를 이용한다.
로컬 기능 테스팅 시 Azure Event Hub는 작업 환경에서 대체될 수 없기 때문에 로컬 기능 테스팅을 위한 인스턴스를 이용한다.