게슈탈트로 이해하는 응집도와 결합도
게슈탈트 원리로 응집도와 결합도를 살펴봅니다.
Feb 14, 2026
들어가며
코드를 읽을 때 맥락이 섞여 있으면 전체를 파악하기 어렵습니다. 하나의 함수 안에 검증, 데이터 가공, API 호출이 뒤섞여 있다면 여기저기 관련 파일을 찾아 헤멘 적 다들 있으실 겁니다.
반대로 관련된 로직끼리 모여 있으면 한눈에 들어옵니다. 인지 심리학에서는 이를 게슈탈트(Gestalt) 원리라고 합니다. 뇌가 가까이 있는 것, 비슷한 것을 자동으로 하나의 덩어리로 묶어서 인식하는 특성입니다.
이 원리는 코드의 응집도와 결합도에도 그대로 적용됩니다. 먼저 게슈탈트가 무엇인지부터 살펴보겠습니다.
게슈탈트란
제프 존슨은 마음을 생각하는 디자인에서 게슈탈트를 이렇게 설명합니다.
"게슈탈트(Gestalt)"는 독일어로 "모양" 또는 "형태"를 뜻합니다. 20세기 초반, 독일 심리학자들은 인간의 시지각이 전일적(holistic)이라는 사실을 발견했습니다. 우리의 시각 체계는 입력된 정보를 개별 요소로 인식하지 않고, 자동으로 구조를 부여하여 하나의 통합된 형태로 인식합니다.
간단히 말해, 전체는 부분의 합보다 크다는 원리입니다. 개별 요소를 따로따로 보는 게 아니라, 자동으로 패턴을 찾아 전체 구조를 먼저 파악합니다.
코드도 마찬가지입니다. 코드는 텍스트이기 이전에 하나의 시각적 레이아웃이며, 개발자는 코드를 읽기 전 훑어보기(Scanning)를 통해 구조를 먼저 파악합니다. 이때도 게슈탈트 원리가 적용됩니다.
게슈탈트 심리학자들은 우리가 시각 정보를 그룹화하는 방식을 여러 원리로 정리했습니다. 이 글에서는 코드와 직접 연결되는 두 가지를 살펴볼까 합니다.
- 근접성(Proximity) - 가까운 것끼리 묶여 보인다
- 유사성(Similarity) - 비슷한 것끼리 묶여 보인다
근접성 (Proximity)
다른 사물들에 비해 상대적으로 가까이 놓여 있는 사물들은 서로 묶여 있는 것처럼 보이고, 상대적으로 멀리 떨어져 있는 사물들은 서로 묶여 있지 않은 것으로 보입니다. — 제프 존슨, 마음을 생각하는 디자인
UX/UI에서의 적용
가장 흔한 예시는 폼(Form)입니다. label과 input이 멀리 떨어지면 "이게 무슨 필드지?"라고 혼란스럽지만, 가까이 붙어있으면 뇌가 자동으로 하나의 입력 요소로 인식합니다.
버튼도 마찬가지입니다. "확인"과 "취소"는 가까이 두고, "삭제" 같은 위험한 액션은 떨어뜨려 놓아 실수를 방지합니다.

코드에서의 적용
UX/UI와 똑같은 원리를 코드에도 적용합니다. 관련된 것을 가까이 배치하고, 다른 로직은 빈 줄로 분리합니다.
예시 1: 함수 내부 로직 그룹화
// Bad: 로직이 구분 없이 나열됨
const handleSubmit = async (data) => {
const valid = schema.parse(data);
if (!valid) return;
const body = { email: data.email, pw: data.password };
setLoading(true);
await api.signup(body);
setLoading(false);
router.push('/welcome');
};
// Good: 논리적 단계에 따라 그룹핑
const handleSubmit = async (data) => {
// 1. 검증
const valid = schema.parse(data);
if (!valid) return;
// 2. 데이터 가공
const body = { email: data.email, pw: data.password };
// 3. API 요청
setLoading(true);
try {
await api.signup(body);
router.push('/welcome');
} catch (error) {
handleError(error);
} finally {
setLoading(false);
}
}; 빈 줄을 넣고 논리적 단계로 구분했을 뿐이지만, 각 단계가 한눈에 들어옵니다.
예시 2: import 그룹화
다음은 Feature-Sliced Design(FSD) 아키텍처를 사용하는 프로젝트의 import 구문입니다. FSD는 코드를 계층별로 구조화하는 방법론으로, app(앱 설정), entities(비즈니스 로직), shared(공통 유틸)처럼 의존성 방향이 명확한 계층으로 나눕니다.
// Bad: import가 뒤섞여 있음
import { useState } from 'react';
import { signupSchema } from '../model/signup.schema';
import { useSignup } from '@/entities/auth';
import { ButtonBox } from '@repo/ui';
import useVerificationCode from '../model/hooks/useVerificationCode';
import { useDaumPostcode } from '@/shared';
import { Link } from 'react-router-dom';
import banner from '@/shared/assets/images/login/banner.png';
import { ROUTE_PATHS } from '@/app/routes/paths';
import type { SignupFormType } from '../model/signup.type'; 외부 라이브러리(react), 내부 모듈(@/entities, @/shared), 같은 모듈(../model)이 뒤섞여 있어 의존성 구조를 파악하기 어렵습니다.
근접성 원리를 적용하면:
// Good: 의존성 레벨에 따라 그룹핑
// 1. React/외부 라이브러리
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { useForm } from 'react-hook-form';
// 2. 외부 UI 라이브러리
import { ButtonBox, Checkbox } from '@repo/ui';
// 3. FSD 내부 계층 (app → entities → shared 순)
import { ROUTE_PATHS } from '@/app/routes/paths';
import { useSignup, type SignupErrorCode } from '@/entities/auth';
import { useDaumPostcode, useFieldMessage } from '@/shared';
import banner from '@/shared/assets/images/login/banner.png';
// 4. 같은 feature 내부 (상대 경로)
import { signupSchema, INSTITUTE_TYPES } from '../model/signup.schema';
import useVerificationCode from '../model/hooks/useVerificationCode';
import type { SignupFormType } from '../model/signup.type'; FSD 계층 구조에 따라 그룹핑했습니다.
외부 의존성부터 내부 계층(app → entities → shared), 그리고 같은 feature 내부 순서로 배치하면 import만 봐도 이 컴포넌트가 어떤 것에 의존하는지 한눈에 들어옵니다.
근접성과 응집도
소프트웨어 공학에서는 "관련된 요소들이 얼마나 한곳에 모여 있는가"를 응집도(Cohesion)라고 부릅니다.
코드에서 근접성 원리를 따른다는 건, 결국 응집도를 높인다는 뜻입니다.
유사성 (Similarity)
다른 조건이 모두 동일하다면 서로 비슷해 보이는 사물들이 하나의 묶음으로 인식됩니다. — 제프 존슨, 마음을 생각하는 디자인

UX/UI에서의 적용
프린트 설정의 용지 방향 버튼을 보면, 세로·가로·가로 역방향이 모두 같은 크기의 아이콘으로 나란히 배치되어 있습니다. 같은 형태를 공유하니 사용자는 즉시 하나의 그룹으로 인식합니다.
Form도 마찬가지입니다. 모든 input 필드는 같은 테두리, 같은 크기로 통일되고, 필수 필드는 일관되게 빨간 별표(*)로 표시됩니다.


코드에서의 적용
같은 역할을 하는 요소는 같은 형태로 작성합니다.
네이밍 컨벤션
// Bad: 유사성 없음
const getName = () => {};
const fetchAge = () => {};
const retrieveEmail = () => {}; 세 함수 모두 사용자 정보를 조회하지만, get, fetch, retrieve처럼 동사가 제각각이라 서로 관련 없어 보입니다.
유사성 원리를 적용하면:
// Good: 일관된 네이밍
const getUserName = () => {};
const getUserAge = () => {};
const getUserEmail = () => {}; 모든 함수가 getUser- 접두사를 공유하므로 뇌는 이들을 하나의 그룹으로 인식합니다. 코드를 읽을 때 "아, 이건 사용자 정보 조회 함수들이구나"라고 즉시 파악할 수 있습니다.
코드 패턴
// Bad: 에러 처리 패턴 불일치
try {
await saveUser(user);
} catch (e) {
console.log(e);
}
await saveOrder(order).catch(handleError);
savePayment(payment); // 에러 처리 없음 같은 저장 작업이지만 에러 처리 방식이 제각각입니다. try-catch, .catch(), 에러 처리 없음이 섞여 있어 일관성이 없습니다.
유사성 원리를 적용하면:
// Good: 일관된 에러 처리 패턴
await saveUser(user).catch(handleError);
await saveOrder(order).catch(handleError);
await savePayment(payment).catch(handleError); 세 줄이 동일한 패턴을 따르므로 뇌는 이들을 하나의 그룹으로 인식합니다. 패턴이 일관되기 때문에 만약 어떤 줄에서 .catch()가 빠져 있다면 즉시 눈에 띕니다.
유사성과 일관성
결국 코드에서의 유사성이란 같은 역할을 하는 것들은 같은 모양을 가져야 한다는 원리입니다. 일관된 패턴은 뇌가 코드를 '하나의 그룹'으로 인식하게 만들어, 예외나 차이를 즉시 발견할 수 있게 합니다.
게슈탈트를 형성하는 코드
Kent Beck, Tidy First?에서는 결합도와 응집도에 대해 이렇게 말합니다.
결합도와 응집도는 단순히 프로그램을 실행하는 컴퓨터의 관점에만 그치지 않습니다. 이와 더불어 인간이 코드를 이해하려 할 때도 컴퓨터 코드의 복잡성을 측정하는 척도가 됩니다. 프로그램을 만들든, 수정하든 변경하든 어떤 프로그램을 이해하려면 바로 앞에 있는 코드 조각뿐만 아니라 해당 코드에 의존하거나 영향을 주고받는 다른 코드 조각까지 이해해야 합니다. 모든 코드가 서로 잘 들어맞고, 전체적으로 의미가 있으면 인지 심리학자들이 게슈탈트라고 부르는 것을 형성하는데, 이렇게 되면 바로 앞에 있는 코드 조각을 더 쉽게 이해할 수 있습니다.
Kent Beck의 이야기를 앞서 살펴본 게슈탈트 원리와 함께 정리하면
- 근접성 → 응집도: 관련된 것을 가까이 모아 하나의 맥락으로 인식
- 유사성 → 일관성: 같은 역할은 같은 패턴으로 작성
이 두 가지가 충족되면 코드는 독립적으로 이해 가능한 단위, 즉 게슈탈트를 형성합니다.
그리고 여기서 결합도가 자연스럽게 따라옵니다.
상태, 함수, 컴포넌트가 여러 폴더에 흩어져 있으면 응집도가 낮아집니다. 관련된 것들이 모여 있지 않으니 게슈탈트가 형성되지 않고 하나를 이해하려면 다른 여러 파일을 동시에 봐야 합니다. 결합도가 높아집니다.
반대로 관련된 것들이 한곳에 모여 있으면 그 모듈은 독립적인 단위로 인식됩니다. 게슈탈트가 형성된 모듈은 그것만 봐도 이해할 수 있으니, 자연스럽게 결합도가 낮아집니다.
결국 응집도와 일관성이 게슈탈트를 형성하고, 게슈탈트가 결합도를 낮추게 됩니다.
결론
응집도를 높이고 결합도를 낮춘다는 건, 결국 읽기 쉬운 코드를 만든다는 뜻입니다. 이렇게 짜여진 읽기 쉬운 코드는 다음에 이 코드를 읽을 동료를 위한 배려로도 이어집니다.
코드를 작성할 때, "컴퓨터가 이해할 수 있는가?"보다 "동료가 이해할 수 있는가?"도 같이 생각해보면 어떨까요?
읽어주셔서 감사합니다.
참고 자료
- 마음을 생각하는 디자인
- Kent Beck, Tidy First?
- Law of Similarity | Laws of UX
- Law of proximity | Laws of UX
- https://blog.adplist.org/post/how-netflix-airbnb-design-for-psychology-led-growth
- Proximity Principle in Visual Design - NN/G
- The Laws of Proximity and Common Region in UX Design
- https://uxdesign.cc/using-gestalt-principles-in-ux-design-3fc64614d3ef