명령형 프로그래밍에서는 코드가 일련의 단계적인 명령으로 작성되며, 컴퓨터가 문제를 해결하기 위해 따라야 하는 정확한 작업 순서를 프로그래머가 명시한다.
컴퓨터에게 무엇을 어떻게(How) 할 것인지 지시하는 방식으로 코드를 작성한다.
"무엇(What)"을 수행하는지를 명세하는 방식의 프로그래밍 패러다임입니다. 프로그래머가 컴퓨터에게 어떻게(How) 동작해야 하는지를 명시적으로 지정하지 않고, 코드가 원하는 결과를 선언적으로 표현
단일책임원칙 === 관심사의 분리
명령형 프로그래밍 | 선언형 프로그래밍 | |
---|---|---|
장점 | 단순하고 직관적이다 | 코드의 재사용성과 유지보수성이 좋다 |
단점 | 코드의 재사용성과 유지보수성이 떨어진다 | 코드의 흐름을 이해하기 어렵다 |
여기서 나는 의문이 생겼다.
명령형 프로그래밍에서 객체지향 프로그래밍 방법론은 유지보수와 코드 재사용성이 용이하다고 배운적이 있었다!
그래서 수업 중 명령형 프로그래밍의 단점에서 코드의 재사용성과 유지보수성이 떨어진다는 부분이 잘 이해가 되지 않아 강사님께 질문을 드렸다.
답변!!
const courses = [
{
id: 1,
name: " imperative programming",
},
{
id: 2,
name: "declarative programming ",
},
];
const updateCourses = [...courses];
// 1. 과정 배열을 순환하여 각 과정 이름의 좌우 공백 제거
for (let i = 0, l = updateCourses.length; i < l; i++) {
const course = { ...updateCourses[i] };
course.name = course.name.trim();
updateCourses[i] = course;
}
// 2. 과정 배열을 순환하여 각 과정 이름 대문자화
for (let i = 0, l = updateCourses.length; i < l; i++) {
const course = updateCourses[i];
course.name = course.name.toLocaleUpperCase();
}
// 3. 배열 원소의 name 속성의 공백을 밑줄로 변경하는 기능 추가
for (let i = 0, l = updateCourses.length; i < l; i++) {
const course = updateCourses[i];
course.name = course.name.replace(/\s+/g, "_");
}
console.log("변형된 데이터\n", updateCourses);
const subjects = [
{
id: 1,
name: " imperative programming",
},
{
id: 2,
name: "declarative programming ",
},
];
// 1. 객체 이름(name) 속성 좌우 공백 제거 함수 선언
function toTrim(object) {
const newO = { ...object };
newO.name = newO.name.trim();
return newO;
}
// 2. 객체 이름(name) 속성 대문자화 함수 선언
function toUpperCase(object) {
const newO = { ...object };
newO.name = newO.name.toLocaleUpperCase();
return newO;
}
function convertSpaceToUnderScore(object) {
const newO = { ...object };
newO.name = newO.name.replace(/\s+/g, "_");
return newO;
}
// 3. 과목 이름 "좌우 공백 제거" → "대문자화" 후, 새로운 과목 배열 생성
const updateSubjects = subjects.map((subject) => {
const copySubject = toTrim(subject)
return copySubject
}).map(subject => {
const copySubject = toUpperCase(subject)
return copySubject
});
// 줄이기
const updateSubjects = subjects
.map(toTrim)
.map(toUpperCase)
.map(convertSpaceToUnderScore);
console.log(updateSubjects);
function createCountUpButton(
container,
// 매개변수를 받음과 동시에 구조분해할당과 기본 옵션을 합성
{ count: initialCount = 0, step = 1, max = 20 } = {}
) {
if (!container || container.nodeType !== document.ELEMENT_NODE) {
throw new Error("container는 문서의 요소가 아닙니다.");
}
let count = initialCount;
const countUpButton = document.createElement("button");
const render = (newCount) => {
countUpButton.textContent = String(newCount);
};
const handleCountUp = (e) => {
count += step;
if (count >= max) {
count = max;
render(count);
countUpButton.disabled = true
}else {
render(count);
}
};
countUpButton.setAttribute("type", "button");
countUpButton.classList.add("CountUpButton");
countUpButton.addEventListener("click", handleCountUp);
render(count);
container.append(countUpButton);
}
const demoContainer = document.getElementById("demo");
createCountUpButton(demoContainer);
createCountUpButton(demoContainer, { count: 1, max: 14 });
createCountUpButton(demoContainer, { count: 2 });
createCountUpButton(demoContainer, { count: 3, step: 5 });
// 붕어빵 틀 -> 붕어빵 (객체)
// 붕어빵틀(생성자함수: 클래스)
class CountUpButton {
#config; // 클래스의 비공개(private) 필드(private field) - 클래스 내부에서만 접근 가능
constructor(userOptions) {
// 클래스의 생성자(constructor)
/*
userOptions 매개변수를 받아 기본 설정(defaultProps)과
사용자 지정 옵션을 결합하여 '#config'에 저장
defaultProps에 정의된 기본값은 count: 0, step: 1
*/
this.#config = { ...CountUpButton.defaultProps, ...userOptions };
this.init();
}
init() { // 생성된 인스턴스가 초기화될 때 호출되는 함수
console.log(this.#config);
}
// static field
static defaultProps = {
count: 0,
step: 1,
};
}
// 새로운(new) 붕어빵(객체: 인스턴스) 생성
const firstCountUp = new CountUpButton({
step: 3,
});
const demoContainer = document.getElementById('demo');
demoContainer.append(firstCountUp.render())
읽어보기
https://euid.notion.site/425f9c1f62594be49659e734734cab17
https://react.dev/learn/reacting-to-input-with-state