한줄 요약 :
오늘은 명령형 프로그래밍과 선언형 프로그래밍의 차이 및 왜 선언형 프로그래밍을 써야하는지에 대해 공부했습니다.🔥
📍 오늘 배운 내용
1. 명령형 프로그래밍과 선언형 프로그래밍의 차이
1-1. 명령형 프로그래밍
- 명령형 프로그래밍은 "HOW"를 제시한다.
- 어떤 방법으로 어떻게 할것인지를 중점적으로 나타냄
ex) 명령형 프로그래밍 예시 코드
// 배열을 파라미터로 받으며, 각 요소에 1을 더해서 새로운 배열을 반환해주는 함수
function add(arr) {
let results = [];
for(let i=0; i<arr.length; i++){
results.push(arr[i]+1);
}
return results;
}
1) add라는 함수로 arr 배열을 파라미터로 받는다.
2) results 라는 배열을 선언하고 arr 배열 원소들 각각에 1을 더해서 results 배열에 넣고, 다 넣었으면 results 배열을 반환한다.
-> 이 설명에 의하면 정말 어떻게 할것인지가 명확하게 나타난다.
1-2. 선언형 프로그래밍
- 선언형 프로그래밍은 "WHAT" 을 제시한다.
- 어떤 방법으로 해야하는지보다 무엇을 나타내야 하는지를 묘사
ex) 선언형 프로그래밍 예시 코드
// 배열을 파라미터로 받으며, 각 요소에 1을 더해서 새로운 배열을 반환해주는 함수
function add (arr) {
return arr.map((i) => i+1);
}
앞의 코드와 동일한 기능을 하지만 명령형 프로그래밍은 어떻게 배열의 요소들에 1을 더할지를 설명하는 식으로 작성되었다.
그러나 선언형 프로그래밍은 무엇을 할지만 작성되었다.
어떤 과정을 통해(HOW) 내가 원하는 결과에 도달하는지가 중요한것이 아니라 무엇을 (WHAT) 할건지가 명확하게 보인다.
2. 선언형 프로그래밍을 지향해야 하는 이유
- 선언형 프로그래밍은 해당 코드가 달성하고자 하는 것이 무엇인지 만을 나타내기 때문에 동일한 코드를 다른 프로그램에서 재사용하기 쉽다.
- javascript 에 내장된 map을 이용해 같은 기능을 수행하였는데, 개발자는 map 의 내부 코드가 어떻게 이루어져 있는지 모르지만 신경 쓸 필요 없이 원하는 기능을 구현할 수 있다.
- 선언형 프로그래밍 방식은 가독성을 높이고 상태를 변경하는 모든 지점들이 map 안으로 추상화 되어, 직접 상태를 변경하지 않아도 된다.
즉, 우리가 개발을 할 때 용도에 맞게 설계하는 과정에서 중요한 것은 "WHAT" 이다.
외부 라이브러리를 사용할 때나 api 를 사용할 때 어떻게 X를 사용할거고, 이런 절차로 X를 불러올거고... 이런것보다는 무엇을 나타낼건지 무엇이 필요한지에 집중하는게 더 필요하다.
3. 토글 버튼 만들기 실습을 통한 예시
화면에 버튼 3개 만들고, 각 버튼 클릭 시 가운데 선 그어지도록 만들기
ex) 위 기능을 명령형 프로그래밍으로 작성한 것
const $button1 = document.createElement('button')
$button1. textContent = 'button1'
const $button2 = document.createElement('button')
$button2. textContent = 'button2'
const $button3 = document.createElement('button')
$button3. textContent = 'button3'
const toggleButton = ($button) => {
if($button.style.textDecoration === '')
$button.style.textDecaration = 'line-through'
else
$button.style.textDecaration = ''
}
document.querySelector('#app').appendChild($button1)
document.querySelector('#app').appendChild($button2)
document.querySelector('#app').appendChild($button3)
document.querySelectorAll('#app button').forEach($button => $button.addEventListener('click', (e) => {
toggleButton(e.target)
}))
- 기능을 추가하려면 코드를 끊임없이 반복해야함
- 명령형은 절차에 의존하기 때문에 재사용 및 확장 어려움
ex) 위 기능을 선언형 프로그래밍으로 작성한 것
function ToggleButton({$target,text}){
const $button = document.createElement('button')
$target.appendChild($button)
this.state = {
toggled: false
}
this.setState = (nextState) =>{
this.state = nextState
this.render()
}
this.render = () => {
$button.textContent = text
$button.style.textDecoration = this.state.toggled ? 'line-through' : 'none'
}
$button.addEventListener('click', ()=> {
this.setState({
toggled : !this.state.toggled
})
})
this.render()
}
const body = document.querySelector('body')
new ToggleButton({
$target: body,
text : 'button1'
})
new ToggleButton({
$target: body,
text : 'button2'
})
new ToggleButton({
$target: body,
text : 'button3'
})
- ToggleButton 이라는 이름으로 추상화
- 추후 ToggleButton 에 또다른 기능을 추가하고 싶을 때 추가가 쉬워짐
- 재사용을 통한 확장이 쉬워짐
📍 어려웠던 내용
- 선언형 프로그래밍에 익숙해지는 것 (무작정 for 문 먼저 치고 보는 안 좋은 습관이 있다.)
- 추상화.. 어렵다
📍 궁금한 내용 / 부족한 내용
- 위와 같이 조건이 많아졌을 경우에는 코드 작성하다 내가 뭘 하고 있는지 모를 때가 많다. 꼬이지 않기 위해서는 일단 무작정 코드를 작성하기 보다 어떤걸 해야하는지 주석으로 작성해가면서 해야하는데 나는 일단 무작정 치고 보는 스타일이라 요구사항이 많고 복잡할 때에는 이 부분을 고쳐야 할 것 같다.
- named parameter 를 활용하자
📍 느낀점
for문 투성이로 코드 짰던 과거의 나를 반성하면서 선언형 프로그래밍이 왜 중요한지 다시 한번 뼈를 맞는 하루였다.
실습하면서 보니 이제야 선언형 프로그래밍이 뭔지 감을 잡게 되었고 실제 개발할 때 명령형과 선언형이 어떤 영향을 미치는지도 알게 되었다.
작년 말쯤, 자바스크립트 문법도 잘 몰라서 프로그래머스 레벨0 문제 풀면서 다른 사람들 코드를 보면서 알고리즘 문제 푸는 연습을 했었는데, 그때 다른 사람들 코드를 보면서 명령형 선언형 이런 차이도 모르는 채 아 저렇게 푸는거구나 하고 따라서 풀었던 적이 있었다.
모방해서 풀다 보니 내장 메소드 모를 때 직접 찾아보기도 하고 내가 더 좋은 방법을 생각해냈을 때도 있었다.
확실히 좋은 코드를 짜는 데에는 다른 사람들 코드를 보는게 도움이 많이 됐던 것 같다. (갑자기 추억회상)
일단 for()를 치고 봤던 습관을 버리고 무엇을 나타내야할지를 생각하면서 코드를 작성해야겠다고 더 많이 느꼈고 자바스크립트 내장 매소드에 대해서도 잘 알아야 선언형 프로그래밍을 하는 데에 더 도움이 될 것 같다.
+)
벌써 데브코스 11일차인데 시간이 너무 빠르고,,, 이러다가 갑자기 수료식 날 되어있을 것 같아 무섭다😂
오늘 팀원 분인 동환님한테 코드리뷰 받고 나서 반성을 많이 한 하루였다!
오늘의 TIL 끝!🩵