Boaz
Cursor, Codex, Claude code 같은 AI 도구들이 이제는 개발자의 일상이 되었습니다. 함수를 작성하다 탭 키를 누르면 다음 줄이 자동 완성되고, 요구사항을 설명하면 몇 초 만에 수백 줄의 코드가 생성됩니다.
AI가 코드를 대신 타이핑해주는 시대가 온 것입니다.
하지만 많은 개발자들이 AI를 사용하면서 비슷한 경험을 합니다. “왜 이렇게 만들었지?”, “이게 뭐하는 코드야?”, “버그가 왜 이렇게 많지?” AI가 만든 코드는 빠르지만, 품질은 들쑥날쑥합니다.
그 이유는 간단합니다. AI에게 ‘무엇을’ 만들어야 하는지 명확히 알려주지 않았기 때문입니다.
설계는 단순히 클래스 다이어그램이나 UML을 그리는 게 아닙니다. 설계는 “이 문제를 어떻게 해결할 것인가”에 대한 구체적인 계획입니다.
이런 질문들에 대한 답이 바로 설계입니다.
AI 로 코딩할 때 기억해야 할 원칙입니다.
“로그인 페이지 만들어줘”라고 하면 AI는 평범한 로그인 폼을 만듭니다. 하지만 “Next.js App Router를 사용하고, Server Action으로 인증 처리하며, 실패 시 에러를 toast로 표시하고, 성공 시 이전 페이지로 리다이렉트하는 로그인 페이지”라고 하면 전혀 다른 품질의 코드가 나옵니다.
설계의 구체성이 곧 코드의 품질입니다.
AI를 이해하는 가장 좋은 비유는 “AI는 손”이라는 것입니다.
과거에는 머릿속에 있는 설계를 손으로 직접 타이핑했습니다. 변수명을 정하고, 함수를 만들고, 로직을 구현했습니다. 시간이 오래 걸렸지만, 그 과정에서 설계가 다듬어지기도 했습니다.
이제 AI는 그 타이핑을 대신합니다. 빠르고 정확합니다. 하지만 AI는 생각하지 못합니다. 우리가 말한 대로만 만들 뿐입니다.
AI 코딩 시대의 개발자는 다음을 책임집니다:
이것이 바로 설계입니다.
AI는 설계를 받아 코드로 구현합니다:
AI는 “어떻게(How)”를 담당합니다. 하지만 ”무엇을(What)”, “왜(Why)”는 우리가 정해야 합니다.
많은 개발자들이 “좋은 프롬프트를 작성하는 법”을 찾습니다. 하지만 진짜 답은 간단합니다.
좋은 설계가 있으면 좋은 프롬프트는 자동으로 나옵니다.
설계가 명확하면, 그것을 AI에게 설명하는 것은 어렵지 않습니다. 반대로 설계가 모호하면, 아무리 프롬프트를 잘 써도 결과는 엉망입니다.
프롬프트는 마법의 주문이 아닙니다. 설계를 AI가 이해할 수 있는 형태로 표현한 것입니다.
예를 들어, 당신의 머릿속에 이런 설계가 있다고 해봅시다:
도서 목록 페이지를 만든다.
- 데이터는 외부 API에서 가져온다
- 서버에서 미리 렌더링해서 SEO를 챙긴다
- 로딩 상태는 Suspense로 처리한다
- 에러는 Error Boundary로 잡는다
이것을 프롬프트로 변환하면:
Next.js App Router를 사용해 도서 목록 페이지를 작성해줘.
요구사항:
- app/books/page.tsx를 Server Component로 작성
- 외부 API (https://api.example.com/books)에서 도서 목록 fetch
- loading.tsx와 error.tsx를 함께 생성
- Suspense와 Error Boundary 활용
- Tailwind CSS로 스타일링
프롬프트는 설계의 번역본입니다.
같은 기능이라도 프롬프트의 구체성에 따라 결과가 완전히 달라집니다.
모호한 프롬프트:
책 목록 보여주는 페이지 만들어줘
구체적인 프롬프트:
Next.js App Router 기반으로 도서 목록 페이지 작성
파일 구조:
- app/books/page.tsx (Server Component)
- app/books/loading.tsx
- app/books/error.tsx
기술 요구사항:
- fetch로 데이터 가져오기 (cache: ‘no-store’)
- TypeScript로 Book 타입 정의
- Grid 레이아웃 (3열, 반응형)
- 각 책 카드에 이미지, 제목, 저자, 가격 표시
- Tailwind CSS 사용
비즈니스 로직:
- 가격이 30,000원 이상이면 ‘베스트셀러’ 배지 표시
- 재고가 0이면 ‘품절’ 표시
첫 번째는 AI가 추측해서 만듭니다. 두 번째는 정확히 우리가 원하는 것을 만듭니다.
이것이 AI 코딩의 핵심 흐름입니다.
머릿속 설계 (구체적)
↓
프롬프트 작성 (명확한 번역)
↓
AI 구현 (정확한 코드)
↓
최소한의 리뷰와 수정
설계가 부실하면 이 흐름이 무너집니다. 프롬프트는 애매해지고, AI는 헤매고, 우리는 코드를 수정하느라 더 많은 시간을 씁니다.
중요한 통찰이 하나 있습니다. 프롬프트는 처음부터 완벽할 필요가 없습니다.
대신 AI와 대화하면서 프롬프트를 발전시킬 수 있습니다:
이 반복 과정에서 프롬프트는 점점 구체적이고 정확해집니다. 이것이 “프롬프트 플랜 모드” — 사람과 AI가 함께 프롬프트를 완성해가는 과정입니다.
AI 코딩은 다음과 같은 단계를 거칩니다.
1. 문제 정의 (사람)
- 무엇을 만들 것인가?
- 왜 만드는가?
- 성공 기준은 무엇인가?
2. 설계 (사람)
- 데이터 구조 설계
- UI 구조 설계
- 기술 스택 선택
- 아키텍처 결정
3. 프롬프트 명세 (사람 + AI)
- 설계를 구체적 언어로 변환
- 파일 구조, 함수명, 역할 명시
- AI와 대화하며 구체화
4. AI 코딩 (AI)
- 코드 생성
- 파일 생성
- 테스트 작성
5. 검증 리뷰 (사람)
- 설계 의도대로 구현되었는가?
- 코드 품질은 적절한가?
- 버그는 없는가?
명확히 구분하면
사람의 역할:
AI의 역할:
AI는 실행자(Executor)이고, 우리는 설계자(Architect)입니다.
실제 개발 예제를 함께 살펴볼게요.
1단계: 초기 요청
“상품 상세 페이지를 만들어줘”
2단계: AI의 질문
- 어떤 정보를 표시해야 하나요?
- 데이터는 어디서 가져오나요?
- 장바구니 기능이 필요한가요?
- 서버 렌더링이 필요한가요?
3단계: 설계 구체화
상품 상세 페이지 (Next.js App Router)
데이터:
- API: GET /api/products/[id]
- 필드: id, name, price, description, images[], stock
UI 구조:
- 이미지 갤러리 (왼쪽)
- 상품 정보 (오른쪽)
- 장바구니 버튼 (클라이언트 컴포넌트)
기술 선택:
- Server Component로 데이터 fetch
- 장바구니 버튼만 Client Component
- Optimistic UI 적용
4단계: AI 구현
이제 AI는 정확히 원하는 코드를 만들 수 있습니다.
이것은 직관과 반대처럼 보이지만 사실입니다.
설계가 모호할 때:
설계가 구체적일 때:
설계에 10분 투자하면, 리뷰에서 30분을 절약합니다.
좋은 코드는 무엇일까요?
가독성? 성능? 재사용성? 물론 다 중요합니다. 하지만 가장 중요한 것은 ”변화에 유연한 코드”입니다.
소프트웨어는 끊임없이 변합니다. 요구사항이 바뀌고, 디자인이 수정되고, 비즈니스 로직이 추가됩니다. 좋은 설계란 이런 변화를 최소한의 수정으로 수용할 수 있는 구조입니다.
도메인 단위 응집도는 간단한 원칙입니다:
“같은 이유로, 같은 타이밍에 변하는 것들을 함께 묶어라”
예를 들어봅시다.
나쁜 구조:상품 카드의 디자인이 바뀌면? Card.tsx, product.tsx, 그리고 상품을 쓰는 모든 곳을 수정해야 합니다.
components/
Button.tsx # 모든 버튼
Input.tsx # 모든 입력
Card.tsx # 모든 카드
pages/
product.tsx # 상품 페이지
cart.tsx # 장바구니 페이지
좋은 구조:
app/
products/
page.tsx # 상품 목록
[id]/page.tsx # 상품 상세
_components/
ProductCard.tsx # 상품 전용 카드
ProductImage.tsx # 상품 이미지
_lib/
getProducts.ts # 상품 데이터 fetch
상품 관련 변경사항은 products 폴더 안에서만 일어납니다. 변화의 범위가 명확합니다.
도메인 단위 응집도를 높이는 질문들
Next.js App Router는 이 철학을 파일 시스템 수준에서 구현했습니다.
app/
products/ # 상품 도메인
page.tsx # 라우트
loading.tsx # 로딩 상태
error.tsx # 에러 처리
layout.tsx # 레이아웃
_components/ # 도메인 전용 컴포넌트
_lib/ # 도메인 로직
상품 관련 모든 것이 한 폴더에 있습니다. 데이터, UI, 로딩, 에러, 레이아웃까지. 이것이 바로 도메인 단위 응집도입니다.
Next.js App Router는 명확한 철학을 가지고 있습니다:
“모든 것을 기본적으로 서버에서 처리하라”
이것은 단순한 기술 선택이 아니라 설계 철학입니다.
전통적인 React 개발:
// 클라이언트에서 데이터 fetch
function ProductList() {
const [products, setProducts] = useState([]);
useEffect(() => {
fetch(’/api/products’)
.then(res => res.json())
.then(setProducts);
}, []);
return <div>{/* UI */}</div>;
}
Next.js App Router 방식:
// 서버에서 데이터 fetch 후 렌더링
async function ProductList() {
const products = await fetch(’/api/products’).then(r => r.json());
return <div>{/* UI */}</div>;
}
차이가 보이시나요?
왜 서버에서 처리해야 할까요?
설계 관점에서 중요한 점:
서버 퍼스트 철학과 도메인 응집도는 완벽히 맞아떨어집니다.
// app/products/page.tsx
async function ProductsPage() {
// 1. 데이터 fetch (서버)
const products = await getProducts();
// 2. UI 렌더링 (서버)
return (
<div>
{products.map(product => (
// 3. 상품 카드 컴포넌트 (서버)
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
데이터와 UI가 한 곳에 있고, 모두 서버에서 처리됩니다. 이것이 도메인 단위 응집도 + 서버 퍼스트입니다.
실제 예시로 배워봅시다.
기능 요구사항:
데이터 제약:
GET https://api.bookstore.com/booksinterface Book {
id: string;
title: string;
author: string;
price: number;
coverImage: string;
stock: number;
}
기술 제약:
이 요구사항을 보고 우리는 설계 결정을 내려야 합니다.
옵션 1: CSR (Client-Side Rendering)
‘use client’;
function BooksPage() {
const [books, setBooks] = useState([]);
useEffect(() => { /* fetch */ }, []);
return <div>{/* ... */}</div>;
}
❌ SEO 불리 ❌ 초기 로딩 느림 ❌ 클라이언트 번들 증가
옵션 2: CSR + React Query
‘use client’;
function BooksPage() {
const { data: books } = useQuery([’books’], fetchBooks);
return <div>{/* ... */}</div>;
}
❌ SEO 여전히 불리 ✅ 캐싱과 상태 관리 편함 ❌ 여전히 클라이언트 의존적
옵션 3: SSR (Server-Side Rendering) ✅
async function BooksPage() {
const books = await fetchBooks();
return <div>{/* ... */}</div>;
}
✅ SEO 최적 ✅ 초기 로딩 빠름 ✅ 클라이언트 번들 최소 ✅ 실시간 데이터 (캐싱 안함)
설계 결정: SSR 선택
이유:
이제 설계를 프롬프트로 변환합니다.
Next.js App Router를 사용해 도서 목록 페이지를 작성해주세요.
## 파일 구조
app/books/page.tsx # 메인 페이지 (Server Component)
app/books/loading.tsx # 로딩 상태
app/books/error.tsx # 에러 처리
app/books/_components/BookCard.tsx # 책 카드 컴포넌트
app/books/_lib/getBooks.ts # 데이터 fetch 함수
## 타입 정의
```typescript
interface Book {
id: string;
title: string;
author: string;
price: number;
coverImage: string;
stock: number;
}
```
## 데이터 패칭 (getBooks.ts)
- API: GET https://api.bookstore.com/books
- fetch 옵션: { cache: ‘no-store’ } (실시간 데이터)
- 에러 처리 포함
- TypeScript 타입 안전성 보장
## UI 요구사항 (BookCard.tsx)
1. 레이아웃:
- Grid 3열 (desktop), 2열 (tablet), 1열 (mobile)
- Gap: 1.5rem
- Card에 hover 효과
2. 카드 내용:
- 책 커버 이미지 (16:9 비율, object-fit: cover)
- 제목 (최대 2줄, overflow: ellipsis)
- 저자명
- 가격 (천 단위 콤마, “원” 표시)
3. 비즈니스 로직:
- price >= 30000 → 오른쪽 상단에 “베스트셀러” 배지 (빨간색)
- stock === 0 → “품절” 표시 (회색 처리)
- stock > 0 → 재고 수량 표시
## 스타일링
- Tailwind CSS 사용
- 카드 배경: white
- 그림자: shadow-md, hover시 shadow-lg
- 둥근 모서리: rounded-lg
- 애니메이션: transition-shadow duration-200
## 로딩/에러 처리
- loading.tsx: Skeleton UI (카드 8개)
- error.tsx: 에러 메시지 + 재시도 버튼
## 품질 기준
- TypeScript strict mode
- 접근성: alt 텍스트, semantic HTML
- 성능: 이미지 최적화 (Next.js Image 컴포넌트)
- SEO: 메타 태그 (제목, 설명)
이 프롬프트를 AI 에게 주면 다음과 같은 코드가 생성됩니다
// app/books/page.tsx
import { Metadata } from 'next';
import { getBooks } from './_lib/getBooks';
import BookCard from './_components/BookCard';
export const metadata: Metadata = {
title: '도서 목록 | 우리 서점',
description: '최신 베스트셀러와 다양한 도서를 만나보세요',
};
export default async function BooksPage() {
const books = await getBooks();
return (
<main className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-8">도서 목록</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{books.map((book) => (
<BookCard key={book.id} book={book} />
))}
</div>
</main>
);
}
// app/books/_lib/getBooks.ts
import { Book } from '../types';
export async function getBooks(): Promise<Book[]> {
const res = await fetch('https://api.bookstore.com/books', {
cache: 'no-store', // 실시간 데이터
});
if (!res.ok) {
throw new Error('도서 목록을 불러오는데 실패했습니다');
}
return res.json();
}
// app/books/_components/BookCard.tsx
import Image from 'next/image';
import { Book } from '../types';
export default function BookCard({ book }: { book: Book }) {
const isBestseller = book.price >= 30000;
const isOutOfStock = book.stock === 0;
return (
<div className="bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-200 overflow-hidden">
<div className="relative aspect-[16/9]">
<Image
src={book.coverImage}
alt={`${book.title} 표지`}
fill
className="object-cover"
/>
{isBestseller && (
<span className="absolute top-2 right-2 bg-red-500 text-white text-xs px-2 py-1 rounded">
베스트셀러
</span>
)}
</div>
<div className="p-4">
<h3 className="font-semibold text-lg mb-1 line-clamp-2">
{book.title}
</h3>
<p className="text-gray-600 text-sm mb-2">{book.author}</p>
<p className="text-xl font-bold text-blue-600">
{book.price.toLocaleString()}원
</p>
{isOutOfStock ? (
<p className="text-gray-400 mt-2">품절</p>
) : (
<p className="text-green-600 text-sm mt-2">
재고 {book.stock}개
</p>
)}
</div>
</div>
);
}
설계가 명확했기에 AI는 정확히 우리가 원하는 코드를 만들었습니다.
AI와 일할 때 두 가지 종류의 지식이 필요합니다:
룰 (Rules): 항상 지켜야 하는 원칙
프롬프트 (Prompts): 특정 문제를 위한 설계
룰은 프로젝트의 기술 철학입니다.
예시:
# Next.js App Router 개발 룰
## 아키텍처 원칙
1. 모든 컴포넌트는 기본적으로 Server Component
2. 클라이언트 인터랙션이 필요한 경우만 ‘use client’
3. 데이터 fetch는 Server Component에서 수행
4. 도메인 단위로 폴더 구조 구성
## 코드 품질 기준
1. TypeScript strict mode 활성화
2. ESLint + Prettier 사용
3. 모든 함수에 JSDoc 주석
4. 컴포넌트 단위 테스트 작성
## 파일 네이밍 규칙
1. 컴포넌트: PascalCase (UserProfile.tsx)
2. 유틸 함수: camelCase (formatDate.ts)
3. 상수: UPPER_SNAKE_CASE (API_BASE_URL.ts)
4. 타입: PascalCase + Type suffix (UserType.ts)
## 폴더 구조 규칙
1. 프라이빗 폴더: _ 접두사 (_components, _lib)
2. 라우트 그룹: () 사용 ((auth)/login)
3. 병렬 라우트: @ 사용 (@modal)
이런 룰은 한 번 정의하고, AI에게 항상 참조하도록 합니다.
프롬프트는 구체적인 문제를 위한 설계입니다.
예시:
# 상품 상세 페이지 설계
요구사항: 상품 정보를 보여주고 장바구니에 추가 기능 제공
설계 결정:
1. SSR로 SEO 최적화 (상품 정보는 검색 노출 필요)
2. 장바구니 버튼만 Client Component (인터랙션 필요)
3. Optimistic UI로 사용자 경험 개선
4. Server Action으로 장바구니 추가 처리
파일 구조:
- app/products/[id]/page.tsx (Server Component, 상품 정보 표시)
- app/products/[id]/_components/AddToCartButton.tsx (Client Component)
- app/actions/cart.ts (Server Action)
룰 기반 + 컨텍스트 프롬프트 조합으로 AI 품질 향상
AI에게 작업을 요청할 때:
1. 프로젝트 룰 문서 첨부
2. 구체적 프롬프트 작성
예:
“첨부된 규칙을 따라서, 상품 상세 페이지를 만들어줘.
[구체적 프롬프트 내용...]”
이렇게 하면:
기술 철학 (룰)
- Next.js App Router의 서버 퍼스트 철학을 따른다
- 클라이언트 JS 번들을 최소화한다
- 도메인 단위 응집도를 높인다
품질 기준 (룰)
- 함수는 하나의 책임만 가진다
- 컴포넌트는 300줄을 넘지 않는다
- 중복 코드는 추상화한다
- 테스트 커버리지 80% 이상 유지
비즈니스 로직 (프롬프트)
- 30,000원 이상 상품은 베스트셀러 배지
- 재고 0이면 품절 표시
- VIP 회원은 5% 추가 할인
- 무료배송 기준: 50,000원 이상
룰은 어떻게 만들 것인가(How), 프롬프트는 무엇을 만들 것인가(What)입니다.
좋은 설계인지 확인하는 체크리스트입니다.
질문:
좋은 예:
app/products/
page.tsx # 상품 목록
[id]/page.tsx # 상품 상세
_components/ # 상품 전용 UI
_lib/ # 상품 로직
나쁜 예:
components/
Card.tsx # 모든 카드
utils/
api.ts # 모든 API
pages/
products.tsx
✅ 서버 컴포넌트를 주로 활용했는가
질문:
판단 기준:
Server Component 사용:
✅ 데이터 fetching
✅ 직접 서버 리소스 접근
✅ 민감 정보 포함 (토큰, API 키)
✅ 큰 의존성 패키지 사용
Client Component 사용:
✅ 이벤트 리스너 (onClick 등)
✅ State/Effect 사용
✅ Browser API 사용 (localStorage 등)
✅ 인터랙티브 UI (드래그, 애니메이션)
✅ 클라이언트 JS 번들이 최소화되었는가
질문:
체크 방법:
# 번들 크기 분석
npm run build
# Page Size 확인
최적화 예:
// ❌ 나쁜 예: 전체가 클라이언트
‘use client’;
function ProductPage() {
const [count, setCount] = useState(1);
return (
<div>
<ProductInfo /> {/* 서버에서 가능 */}
<Counter value={count} onChange={setCount} />
</div>
);
}
// ✅ 좋은 예: 필요한 부분만 클라이언트
async function ProductPage() {
return (
<div>
<ProductInfo /> {/* Server Component */}
<CounterButton /> {/* Client Component */}
</div>
);
}
✅ 프롬프트와 룰이 명확히 구분되어 있는가
질문:
확인 사항:
✅ README.md에 기술 철학 명시
✅ 코딩 컨벤션 문서 존재
✅ 아키텍처 가이드 문서 존재
✅ 룰은 Git에서 관리
✅ 프롬프트는 태스크별로 작성
✅ 서버 로직이 클라이언트로 새지 않았는가
질문:
보안 체크:
// ❌ 위험: 클라이언트에서 가격 계산
‘use client’;
function Checkout({ items }) {
const total = items.reduce((sum, item) =>
sum + item.price * item.quantity, 0);
// 클라이언트에서 조작 가능!
}
// ✅ 안전: 서버에서 가격 계산
// app/checkout/page.tsx
async function CheckoutPage() {
const total = await calculateTotal(); // 서버 함수
return <CheckoutUI total={total} />;
}
AI 코딩의 성공은 이 흐름이 명확할 때 나옵니다:
1. 문제를 이해한다 (What & Why)
↓
2. 해결 방법을 설계한다 (How & Structure)
↓
3. 설계를 프롬프트로 번역한다 (Specification)
↓
4. AI가 코드를 구현한다 (Implementation)
↓
5. 설계 의도대로 되었는지 검증한다 (Review)
이 흐름이 깨지는 순간, 품질은 무너집니다.
AI 코딩 시대의 역할 분담은 명확합니다:
개발자의 일:
AI의 일:
우리는 머리이고, AI는 손입니다.
과거에는 좋은 개발자의 기준은 아래를 포함 했습니다:
이제 우리가 더 집중할 좋은 개발자의 기준은 이것입니다:
타이핑 속도는 더 이상 중요하지 않습니다. 사고의 깊이가 중요합니다.
AI가 코드를 쉽게 만들어주기 때문에, 유혹이 있습니다:
“일단 AI한테 만들어달라고 하고, 나중에 고치지 뭐”
이것은 매우 위험합니다.
생각 없이 만든 코드는:
설계 없이 코딩하는 것은 설계도 없이 건물 짓는 것과 같습니다. 빠르게 만들 순 있지만, 결국 무너집니다.
마지막으로 핵심을 정리하면:
AI 코딩의 품질은 프롬프트가 아니라 설계에서 나옵니다.
AI 시대에도, 아니 AI 시대이기 때문에:
설계는 더욱 중요해졌습니다. 타이핑이 빨라진 만큼, 잘못된 방향으로 달려갈 위험도 커졌습니다.
그래서 우리는 더 깊이 생각해야 합니다.
이런 질문에 답할 수 있을 때, AI는 강력한 도구가 됩니다.
실무에서 바로 사용할 수 있는 템플릿입니다.
# [기능명] 설계 문서
## 1. 요구사항
### 기능 요구사항
-
### 비기능 요구사항
-
## 2. 제약조건
### 데이터 제약
-
### 비즈니스 제약
-
### 기술 제약
-
## 3. 설계 결정
### 렌더링 방식
- [ ] SSR (Server-Side Rendering)
- [ ] SSG (Static Site Generation)
- [ ] CSR (Client-Side Rendering)
선택 이유:
### 아키텍처
- 폴더 구조:
- 주요 컴포넌트:
- 데이터 흐름:
## 4. 파일 구조
app/ [domain]/ page.tsx layout.tsx loading.tsx error.tsx _components/ _lib/
## 5. 프롬프트
[AI에게 전달할 구체적인 프롬프트 작성]
## 6. 검증 기준
- [ ] 요구사항이 모두 구현되었는가?
- [ ] 서버 컴포넌트를 주로 사용했는가?
- [ ] 도메인 단위로 응집도가 높은가?
- [ ] 에러 처리가 적절한가?
- [ ] 타입 안전성이 보장되는가?
AI 코딩은 마법이 아닙니다. 좋은 설계를 빠르게 구현하는 도구일 뿐입니다.
설계 없는 AI 코딩은 나침반 없이 항해하는 것과 같습니다.
당신의 설계가 곧 당신의 코드입니다.
AI와 함께하는 다음 프로젝트에서 ‘설계’에 10분만 더 투자해보세요. 그 10분이 몇 시간을 절약해줄 것입니다.