카테고리 없음
명령형/선언적 프로그래밍
노엠디엔
2024. 10. 12. 15:00
명령형 프로그래밍 (Imperative Programming)
프로그램의 상태를 변경하는 명령문의 시퀀스로 구성된다.
어떻게(How) 구성할지에 초점을 맞추어 목표를 달성하기 위한 각 단계를 기술한다.
C, Java의 절차적 부분, 저수준코드
- 고수준 언어(High-Level Language): 고수준 언어는 프로그래밍 언어가
영어와 한국어와 같은 인간의 언어에 가깝게 작성되어,
사람이 이해하기 쉬운 형태로 구성됩니다.
Python, JAVA, JavaScript와 같은 언어가 고수준 언어에 해당합니다. - 저수준 언어(Low-Level Language): 저수준 언어는 컴퓨터가 직접 이해하는
더 기술적인 언어를 뜻함 저수준 언어는 기계어(컴퓨터의 언어)와 매우 유사하며,
컴퓨터의 메모리와 프로세서를 직접 제어한다.
어셈블리 언어와 대표적인 저수준 언어에 해당합니다.
선언적 프로그래밍 (Declarative Programming)
원하는 결과를 명시하고 그 결과를 얻기 위해 구체적인 단계는 추상화여 설계
무엇(What)을 할지에 초점을 맞춘다.
프로그램의 로직을 직접 기술하지 않고, 원하는 결과를 설명한다.
SQL, HTML 함수형 프로그래밍 언어
- 함수형 프로그래밍(Functional Programming)은 프로그래밍 패러다임 중 하나로,
프로그램의 로직을 함수로 구성하고,
데이터를 변경하지 않으며 순수 함수(Pure Function)를 사용하는 방식을 강조한다.
- 불변성 (Immutability) :함수형 프로그래밍에서는 데이터가 변경되지 않습니다.
모든 데이터는 불변 객체로 간주되며, 데이터의 변경이 필요한 경우
기존 데이터를 복사하여 새로운 데이터를 생성합니다. - 고차 함수 (Higher-Order Function):함수를 인자로 받거나 함수를 반환하는 함수를 말합니다.
고차 함수는 코드를 더 추상화하고 재사용성을 높입니다. - 부작용 없음 (No Side Effects):함수가 외부 상태를 변경하지 않기 때문에
함수의 실행이 프로그램의 다른 부분에 영향을 주지 않습니다. - 일급 객체로서의 함수 (First-Class Function):함수가 일급 객체로 취급되며, 변수에 할당되거나
다른 함수의 인자로 전달될 수 있습니다.
- 불변성 (Immutability) :함수형 프로그래밍에서는 데이터가 변경되지 않습니다.
리액트에서는 선언형 프로그래밍으로 컴포넌트 작성하는 것을 권장하고 있다.
밑에 예시로 알아보자.
import React, { useState } from 'react';
function ImperativeComponent() {
// 상태 및 로직을 컴포넌트 내부에서 모두 처리
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const addItem = () => {
setItems([...items, `Item ${items.length + 1}`]);
};
return (
<div>
<h3>Item List</h3>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<button onClick={addItem}>Add Item</button>
</div>
);
}
export default ImperativeComponent;
위코드는 상태와 버튼에 대한 함수와 UI처리까지 한 번에 처리하는
명령형 프로그래밍 방식에 코드로써
어떤 절차를 통해 결과를 도출할지에 대해 집중하여 아이템을 추가하는 방법과 UI를 어떻게 업데이트할지에 집중
- 명시적 절차: addItem 함수는 새로운 아이템을 배열에 추가하기 위해 명시적으로 배열을 복사하고,
새로운 아이템을 추가함 - UI 갱신: map() 함수는 아이템 리스트를 그리기 위해 모든 아이템을 순회하며 직접
그리는 방법을 명시합니다.
재사용성을 중요시하는 리액트에서는 위코드와 같은컴포넌트는
재사용하기 힘들고 상태나 함수가 변할시 해당컴포넌트 전체가 재렌더링되므로
이러한 프로그래밍 방식은 권장하지 않는 것 같다.
import { useState } from 'react';
// 커스텀 훅: 아이템 관리 로직을 담음
function useItemManager(initialItems) {
const [items, setItems] = useState(initialItems);
const addItem = () => {
setItems([...items, `Item ${items.length + 1}`]);
};
return {
items,
addItem,
};
}
import React from 'react';
import { useItemManager } from './useItemManager'; // 커스텀 훅 불러오기
// 개별 아이템을 렌더링하는 컴포넌트
function ListItem({ item }) {
return <li>{item}</li>;
}
// 아이템 리스트를 렌더링하는 컴포넌트
function ItemList({ items }) {
return (
<ul>
{items.map((item, index) => (
<ListItem key={index} item={item} />
))}
</ul>
);
}
// 버튼을 렌더링하는 컴포넌트
function AddItemButton({ onAdd }) {
return <button onClick={onAdd}>Add Item</button>;
}
// 상위 컴포넌트 - 비즈니스 로직을 커스텀 훅에서 가져옴
function DeclarativeComponent() {
const { items, addItem } = useItemManager(['Item 1', 'Item 2', 'Item 3']);
return (
<div>
<h3>Item List</h3>
<ItemList items={items} />
<AddItemButton onAdd={addItem} />
</div>
);
}
export default DeclarativeComponent;
위코드는 선언적 프로그래밍 방식으로 작성한 컴포넌트로써 비니지스 로직은
커스텀훅으로 분리,컴포넌트는 UI를 보여주는 역할만 수행하게 된다.
컴포넌트마다 무엇을해야할지에 초점을 맞춰 하나의 역할만 할 수 있게 단일책임 원칙에 집중한다.
- 커스텀 훅 (useItemManager):
- 아이템 목록 관리 및 추가 로직을 담당
- items와 addItem을 반환하여 컴포넌트에서 쉽게 사용할 수 있게 함.
- 컴포넌트 (DeclarativeComponent):
- 비즈니스 로직이 커스텀 훅으로 분리되었으므로, items와 addItem을 커스텀 훅에서 가져와 사용.
- 상태 관리, 비즈니스 로직에 대한 코드를 별도로 작성할 필요 없이, 뷰만 관리