[JS] todo 앱 만들면서 프로그래밍 디자인하기
todo앱을 만들며 프로그래밍을 디자인해보자
MISSION : 할 일 관리 프로그램
- 미션 목표
- todo.js 함수 설계와 코드 구현 후, PR하기
- 학습 내용
- pesudo code 와 skeleton code 가 무엇인지 살펴본다
- 먼저 설계하고 코딩하는 습관을 가진다
- 페어 프로그래밍을 하며 설계의 중요성을 몸소 체험한다
고차 함수를 왜 쓰는가? forEach, map, filter, some, every …
- 가독성 향상! 간결해서 판단에 도움이 된다
- 메서드 체이닝 지원
- 메서드 체이닝 : 문제를 쪼개서 볼 수 있게 해준다 *> 함수 하나에 문제 해결 하나! *> 코드 재사용에 용이하다 *> 생산성 향상!
- 테스트 코드를 쉽게 작성할 수 있다
- 원래의 데이터를 수정하지 않는다
- 목적을 생각하면서 각 기능들을 쓰자
슈퍼조커 reduce
- 확실한 장점 : 다양한 데이터 형태를 좀 더 간편하고 쉽게 return 할 수 있다
- 모든 원하는 형태의 데이터를 만들 수 있다!
- 배열 조작해서 문자열, 숫자, 객체 등 모든 것으로 변형 가능하다
pesudo code
- 컴퓨터 프로그램이나 알고리즘이 수행해야할 내용을 우리가 사용하는 언어 (한국어 또는 영어 등)로 간략히 서술해 놓은 것**
의사 코드를 만들어야 하는 이유
- 실제 코딩하기 전 사고를 명확히 만들어줌
- 코드 리뷰가 쉬워진다
- 코드 실행 없이 하위 설계 단계의 프로그램 검토 가능
- 설계문서와 분리되어 코멘트에 부담이 없다
- 코드 리뷰가 쉬워진다
- 코드 수정 용이
좋은 의사코드의 조건
- 같은 스타일로 일관성있게
- 콤마의 위치, bracket 등등 불필요한 디테일은 무시
- 프로그래밍에 쓰이는 구문을 쓴다
- 한 눈에 알고리즘 전체를 꿰뚫어 볼 수 있게
- 상대방과 커뮤니케이션 수준을 맞추자
의사코드에서 주로 쓰이는 단어
- 입력 : READ, OBTAIN, GET
- 출력 : PRINT, DISPLAY, SHOW
- 계산 : COMPUTE, CALCULATE
- 초기화 : SET, INIT
- 요소 추가 : INCREMENT, BUMP
- 일정한 증가 : SEQUENCE
- 반복 : WHILE, FOR
- 조건문 : IFTHENELSE
- 분기처리 : CASE
- 부울 : TRUE / FALSE
- 출처 : 좋은 의사코드 작성법 https://sujinlee.me/pseudocode
스켈레톤 코드
- Skeleton programming is a style of computer programming based on simple high*level program structures and so called dummy code
- 간단히 말하면, 구현 내용 없이 껍데기만 만들어 놓은 코드
코드 디자인 순서
- 요구 조건 분석
- pseudo code로 논리 조건 정리
- 동료와 함께 리뷰
- skeleton code로 코드 얼개 잡기
- 구현
실습 데이터 & 코드 예시
const todos = [
{
'name' : '자바스크립트 공부하기',
'tags' : ['programming', 'javascript']
'status' : 'todo'
'id' : 12123123
},
{
'name' : ' 그림 그리기',
'tags' : ['picture', 'favorite']
'status' : 'doing'
'id' : 312323
}
....
];
const show = (obj) => {
...
}
show("all");
show("todo");
결과 예시
$ nodejs todos.js
현재상태 : todo: 1개, doing:2개, done:4개
todo리스트 : 총3건 : ' 자바스크립트 공부하기' , 'iOS공부하기'
1. 요구 조건 분석
- show 함수를 실행했을 때, 전달되는 parameter의 종류에 따라 결과값이 달라진다
"all"
이었을 때,status : count
형식으로 값이 출력된다"type"
이었을 때,count : name list
형식으로 값이 출력된다
- 구체적으로 각 case별 상황을 생각해본다면
- input arguements
- 인자가 all일 때
- 특정 status 값이 들어올 때 (todo, doing, done)
- 잘못 입력되었을 때
- output data
- all *> 각 status의 데이터 개수
- 각 status *> status의 데이터 개수, name 목록
- final goal
- 각 data를 템플릿에 맞춰 표준 출력
- input arguements
2. 접근 전략 설정
- parameter에 따라 다른 데이터를 출력해야 하는 것처럼 보임
- 하지만
{ status : [name_list] }
객체 생성으로 두 가지 데이터를 동시에 출력 가능- 각 status 개수는 해당 객체의 배열 length로 대체
- name 목록은 status를 키로 가지는 name_list
- 데이터 접근이 빈번하다고 가정했을 경우, 객체를 만들어 데이터를 전처리하는 함수를 따로 두는 편이 효율적
- show(todolist) 함수는 객체의 데이터를 출력할 뿐, 처리는 전처리 함수에 위임한다
3.pseudo code 작성
OBJECT DATA = {"TODO" : NAME ARRAY, "DOING": NAME ARRAY, "DONE": MAME ARRAY};
INIT_DATA(DATA) {
FOR (OBJ OF TODOS)
IF (OBJ === "TODO") THEN OBJ.NAME *> DATA.TODO
ELSEIF (OBJ === "DOING") THEN OBJ.NAME *> DATA.DOING
ELSEIF (OBJ === "DONE") THEN OBJ.NAME *> DATA.DONE
}
SHOW(INPUT) {
IF (INPUT === "ALL")
PRINT (STATUS : STATUS.LENGTH)
ELSEIF (INPUT == DATA.KEY)
PRINT (DATA.KEY : count_name_list, [name_list])
ELSE ERROR HANDLING;
}
실제 작성한 코드
const dataObj = {"todo" :[], "doing": [], "done":[]};
const initData = (todos) => {
todos.forEach((val) => {
if (val.status === "todo") dataObj.todo.push(val.name);
if (val.status === "doing") dataObj.doing.push(val.name);
if (val.status === "done") dataObj.done.push(val.name);
});
};
const show = (todosType) => {
if (todosType === "all")
console.log(`todo : ${dataObj.todo.length}, doing : ${dataObj.doing.length}, done : ${dataObj.todo.length}`);
else if (Object.keys(dataObj).includes(todosType)) {
Object.keys(dataObj).forEach((val) => {
if (val === todosType) {
console.log(`todo리스트 : 총 ${dataObj[todosType].length} : ${dataObj[todosType].join()}`);
};
})
} else {
throw new Error("데이터 형식이 일치하지 않습니다");
}
}
Date:
Tags:
JS