변수명 작성 가이드 접두사와 접미사 활용법칙
개요
개발에서 명확하고 일관성 있는 변수명은 코드의 가독성과 유지보수성을 크게 향상시킨다. 이때 변수명에 대해서 제대로 작성되지 않으면 유지보수가 매우 어렵다. 이를 위해서는 꼭 팀 내부적으로 결정해야하는접두사와 접미사들이 있다. 꼭 팀 내부적으로 결정하거나 최근에는 cursor rule이나 system.md로 만들어서 ai들에게도 공유가 필요하다.
1. Boolean 값을 나타내는 접두사
Boolean 변수는 true/false 값을 가지므로, 질문 형태의 접두사를 사용하여 직관적으로 표현합니다.
접두사 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
is | 상태나 속성을 나타낼 때 | isLoading , isVisible , isActive , isValidated , isAuthenticated | 가장 일반적인 Boolean 접두사 |
has | 소유나 포함 관계를 나타낼 때 | hasPermission , hasDiscount , hasChildren , hasError , hasNextPage | 무언가를 가지고 있는지 표현 |
can | 능력이나 권한을 나타낼 때 | canEdit , canDelete , canAccess , canSubmit , canRefresh | 할 수 있는지 없는지를 표현 |
Boolean 접두사 사용 예시
// 상태 관리
const isLoading = true;
const isFormValid = checkFormValidation();
const hasUnsavedChanges = checkForChanges();
const canSubmitForm = isFormValid && !hasUnsavedChanges;
// 권한 체크
const canViewProfile = user.permissions.includes('view_profile');
2. 데이터 조작 함수의 접두사
데이터를 다루는 함수들은 그 동작 방식과 특성에 따라 접두사를 구분하여 사용합니다.
데이터 가져오기 (Retrieval)
접두사 | 사용 목적 | 예제 | 상세 설명 |
---|---|---|---|
get | 이미 존재하는 데이터를 즉시 반환 | getUserData() , getStoredValue() , getCurrentTime() | 동기적으로 즉시 사용 가능한 데이터 |
fetch | 외부 API나 원격 서버에서 데이터 요청 | fetchUserProfile() , fetchProducts() , fetchWeatherData() | 비동기적으로 네트워크 통신이 필요한 경우 |
load | 화면 렌더링이나 초기화와 함께 데이터 로딩 | loadDashboard() , loadUserInterface() , loadPageContent() | UI 변경을 동반하는 데이터 로딩 |
데이터 수정하기 (Modification)
접두사 | 사용 목적 | 예제 | 상세 설명 |
---|---|---|---|
set | 값을 설정하거나 교체 | setUser() , setConfiguration() , setTheme() | 완전히 새로운 값으로 덮어쓰기 |
update | 기존 값의 일부를 수정 | updateProfile() , updateStatus() , updatePassword() | 부분적인 변경사항 적용 |
데이터 추가/제거 (Addition/Removal)
접두사 | 사용 목적 | 예제 | 상세 설명 |
---|---|---|---|
add | 새로운 데이터 추가 | addUser() , addToCart() , addComment() | 기존에 없던 새로운 항목 추가 |
remove | 데이터 제거 | removeUser() , removeFromCart() | 특정 항목을 찾아서 제거 |
delete | 데이터 완전 삭제 | deleteAccount() , deleteFile() | 영구적인 삭제 작업 |
clear | 전체 데이터 비우기 | clearCache() , clearForm() , clearHistory() | 모든 데이터를 한번에 제거 |
3. 조건과 필터링을 나타내는 접두사/접미사
데이터를 특정 조건에 따라 필터링하거나 그룹화할 때 사용하는 패턴입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
by | 특정 기준으로 그룹화 | productsByCategory , usersByRole , ordersByDate , salesByRegion | 기준점을 명확히 표현 |
from | 특정 출처나 시점부터 | ordersFromLastMonth , usersFromKorea , dataFromAPI , messagesFromToday | 시작점이나 출처를 나타냄 |
to | 특정 대상이나 종점까지 | emailsToAdmin , transferToAccount , redirectToLogin | 목적지나 대상을 표현 |
above | 특정 값보다 큰 | scoresAboveAverage , pricesAbove100 , usersAboveAge18 | 초과 조건 |
필터링 예시
// 조건별 데이터 필터링
const productsByCategory = filterProductsByCategory('electronics');
const ordersFromLastWeek = getOrdersFromDateRange(lastWeek, today);
const highValueCustomers = getCustomersWithinSpendingRange(1000, 10000);
const recentActiveUsers = getUsersAboveActivityScore(80);
// 복합 조건 예시
const premiumUsersFromSeoul = users
.filter(user => user.city === 'Seoul')
.filter(user => user.subscriptionType === 'premium');
4. 컬렉션과 자료구조를 나타내는 접미사
데이터의 구조와 타입을 명확하게 표현하는 접미사들입니다.
접미사 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
Array | 배열 구조 강조 | numberArray , stringArray , objectArray | 배열임을 명확히 표현 |
Map | 키-값 쌍의 맵 구조 | userMap , configMap , categoryMap | Map 객체나 딕셔너리 |
Set | 중복 없는 집합 | uniqueIdsSet , tagSet , permissionSet | Set 객체나 고유값 집합 |
Queue | 선입선출 구조 | taskQueue , messageQueue , printQueue | 큐 자료구조 |
Stack | 후입선출 구조 | operationStack , navigationStack | 스택 자료구조 |
Tree | 트리 구조 | categoryTree , organizationTree , menuTree | 계층적 구조 |
Graph | 그래프 구조 | relationshipGraph , networkGraph | 노드와 엣지로 구성된 그래프 |
컬렉션 접미사 사용 예시
// 명확한 자료구조 표현
const activeUserList = users.filter(user => user.isActive);
const productCategoryMap = new Map([
['electronics', electronicsProducts],
['clothing', clothingProducts]
]);
const uniqueTagsSet = new Set(allTags);
const taskQueue = new Queue();
const navigationStack = [];
// 복잡한 데이터 구조
const departmentTree = {
name: 'Company',
children: [
{ name: 'Engineering', children: [] },
{ name: 'Marketing', children: [] }
]
};
5. 상태와 단계를 나타내는 접미사
애플리케이션의 상태나 처리 단계를 표현할 때 사용하는 접미사들입니다.
접미사 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
Status | 현재 상태 | connectionStatus , paymentStatus , orderStatus | 현재의 상태 정보 |
State | 상태 객체 | applicationState , gameState , formState | 상태를 관리하는 객체 |
Mode | 동작 모드 | editMode , viewMode , debugMode | 시스템의 동작 방식 |
Type | 타입이나 종류 | userType , messageType , errorType | 분류나 유형 |
6. 시간과 관련된 접두사/접미사
시간, 날짜, 기간과 관련된 변수명에 사용하는 패턴들입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
start | 시작 시점 | startTime , startDate , sessionStart | 시작을 나타냄 |
end | 종료 시점 | endTime , endDate , sessionEnd | 종료를 나타냄 |
last | 마지막 또는 이전 | lastLogin , lastUpdate , lastModified | 가장 최근의 과거 |
next | 다음 | nextUpdate , nextSchedule , nextId | 앞으로 올 것 |
current | 현재 | currentTime , currentUser , currentPage | 지금 현재의 상태 |
previous | 이전 | previousValue , previousPage , previousUser | 바로 앞의 상태 |
시간 관련 예시
// 시간 관련 변수들
const sessionStartTime = new Date();
const loginTimeout = 30 * 60 * 1000; // 30분
const autoSaveInterval = 5 * 60 * 1000; // 5분
const lastBackupDate = getLastBackupDate();
const nextScheduledMaintenance = calculateNextMaintenance();
// 기간 계산
const sessionDuration = Date.now() - sessionStartTime;
const processingDelay = Math.random() * 1000; // 0-1초 랜덤 지연
7. 이벤트와 콜백 함수 네이밍
사용자 상호작용이나 시스템 이벤트를 처리하는 함수들의 명명 규칙입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
on | 이벤트 핸들러 | onClick , onSubmit , onLoad , onError | 이벤트가 발생했을 때 |
handle | 이벤트 처리 함수 | handleClick , handleSubmit , handleError | 이벤트를 처리하는 함수 |
before | 사전 처리 | beforeSubmit , beforeClose , beforeSave | 작업 전에 실행 |
after | 사후 처리 | afterSubmit , afterLoad , afterSave | 작업 후에 실행 |
when | 조건부 실행 | whenReady , whenComplete , whenError | 특정 조건일 때 |
이벤트 핸들러 예시
// React 컴포넌트의 이벤트 핸들러
const handleFormSubmit = (event) => {
event.preventDefault();
validateForm();
};
const onUserLogin = (userData) => {
updateUserState(userData);
redirectToProfile();
};
// 생명주기 이벤트
const beforePageUnload = () => {
saveUnsavedChanges();
};
const afterDataLoad = () => {
hideLoadingSpinner();
renderUserInterface();
};
8. 유틸리티와 헬퍼 함수
재사용 가능한 유틸리티 함수들의 명명 패턴입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
format | 데이터 형식 변환 | formatDate , formatCurrency , formatPhoneNumber | 표시 형식으로 변환 |
parse | 문자열을 객체로 변환 | parseJSON , parseDate , parseURL | 파싱 작업 |
validate | 유효성 검사 | validateEmail , validatePassword , validateForm | 검증 함수 |
convert | 단위나 타입 변환 | convertToString , convertCurrency , convertUnit | 단위 변환 |
build | 복잡한 객체 구성 | buildQuery , buildComponent , buildConfiguration | 조립이나 구성 |
9. API와 네트워크 관련 네이밍
외부 서비스와의 통신이나 네트워크 작업에 사용하는 패턴들입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
request | 요청 보내기 | requestUserData , requestPermission | API 요청 |
response | 응답 받기 | handleResponse , parseResponse | API 응답 처리 |
call | API 호출 | callUserAPI , callPaymentService | 서비스 호출 |
send | 데이터 전송 | sendMessage , sendAnalytics | 데이터 송신 |
receive | 데이터 수신 | receiveMessage , receiveUpdate | 데이터 수신 |
upload | 파일 업로드 | uploadImage , uploadDocument | 파일 업로드 |
download | 파일 다운로드 | downloadFile , downloadReport | 파일 다운로드 |
sync | 동기화 | syncData , syncUserPreferences | 데이터 동기화 |
API 관련 예시
// API 통신 관련 함수들
const requestUserProfile = async (userId) => {
const response = await api.get(`/users/${userId}`);
return response.data;
};
const uploadProfileImage = async (imageFile) => {
const formData = new FormData();
formData.append('image', imageFile);
return await api.post('/upload/profile', formData);
};
const syncUserPreferences = async () => {
const localPrefs = getLocalPreferences();
const serverPrefs = await requestServerPreferences();
return mergePreferences(localPrefs, serverPrefs);
};
10. 성능과 최적화 관련 네이밍
성능 향상이나 최적화와 관련된 변수명 패턴들입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
cache | 캐시 관련 | userCache , imageCache , cacheKey | 캐싱 시스템 |
buffer | 버퍼 관련 | dataBuffer , audioBuffer , writeBuffer | 임시 저장소 |
pool | 객체 풀 | connectionPool , threadPool , objectPool | 재사용 가능한 자원들 |
lazy | 지연 로딩 | lazyLoadImages , lazyInitialization | 필요할 때 로딩 |
preload | 사전 로딩 | preloadAssets , preloadNextPage | 미리 로딩 |
throttle | 실행 제한 | throttledUpdate , throttleApiCalls | 실행 빈도 제한 |
debounce | 실행 지연 | debouncedSearch , debounceInput | 연속 실행 방지 |
memo | 메모이제이션 | memoizedResult , memoizeFunction | 결과 캐싱 |
11. 에러와 예외 처리 네이밍
오류 처리와 예외 상황을 다루는 변수명 패턴들입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
error | 에러 객체 | validationError , networkError , authError | 에러 정보 |
exception | 예외 상황 | handleException , customException | 예외 처리 |
fail | 실패 관련 | onFail , failureCallback , failedAttempts | 실패 상황 |
retry | 재시도 관련 | retryCount , retryAttempt , maxRetries | 재시도 로직 |
fallback | 대안 방법 | fallbackValue , fallbackFunction | 대체 방안 |
recovery | 복구 관련 | recoveryMode , dataRecovery | 오류 복구 |
에러 처리 예시
// 에러 처리 패턴
const maxRetryAttempts = 3;
let currentRetryCount = 0;
const handleNetworkError = (error) => {
if (currentRetryCount < maxRetryAttempts) {
currentRetryCount++;
retryRequest();
} else {
showFallbackContent();
}
};
const fallbackUserData = {
name: 'Guest',
role: 'visitor'
};
12. 보안과 권한 관련 네이밍
보안, 인증, 권한과 관련된 변수명 패턴들입니다.
패턴 | 사용 목적 | 예제 | 설명 |
---|---|---|---|
auth | 인증 관련 | authToken , authStatus , authUser | 인증 정보 |
permission | 권한 관련 | userPermissions , hasPermission | 권한 체크 |
role | 역할 관련 | userRole , adminRole , roleBasedAccess | 사용자 역할 |
secret | 보안 정보 | apiSecret , secretKey (주의: 실제로는 환경변수 사용) | 민감한 정보 |
token | 토큰 관련 | accessToken , refreshToken , jwtToken | 인증 토큰 |
secure | 보안 관련 | secureConnection , secureStorage | 보안 기능 |
encrypted | 암호화 관련 | encryptedData , encryptedPassword | 암호화된 데이터 |
13. 실무에서의 네이밍 베스트 프랙티스
일관성 유지하기
// 좋은 예: 일관된 패턴
const fetchUserData = async () => { /* API 호출 */ };
const fetchProductData = async () => { /* API 호출 */ };
const fetchOrderData = async () => { /* API 호출 */ };
// 나쁜 예: 혼재된 패턴
const getUserData = async () => { /* API 호출 */ };
const fetchProductData = async () => { /* API 호출 */ };
const loadOrderData = async () => { /* API 호출 */ };
의미 있는 구체성
// 좋은 예: 구체적이고 명확한 이름
const submitPaymentForm = () => { /* 결제 양식 제출 */ };
const validateEmailAddress = (email) => { /* 이메일 검증 */ };
const calculateShippingCost = (weight, distance) => { /* 배송비 계산 */ };
// 나쁜 예: 모호하고 일반적인 이름
const submit = () => { /* 무엇을 제출하는지 불명확 */ };
const validate = (input) => { /* 무엇을 검증하는지 불명확 */ };
const calculate = (a, b) => { /* 무엇을 계산하는지 불명확 */ };
팀 컨벤션 따르기
팀에서 합의된 네이밍 컨벤션을 문서화하고 일관되게 적용하는 것이 중요합니다. 코드 리뷰 시에도 네이밍 컨벤션을 체크 포인트로 포함시켜 품질을 유지할 수 있습니다.
결론
체계적인 변수명 작성은 코드의 가독성과 유지보수성을 크게 향상시킵니다. 위에서 제시한 패턴들을 참고하여 프로젝트의 성격에 맞는 네이밍 컨벤션을 정립하고, 팀 전체가 일관되게 적용한다면 더욱 품질 높은 코드를 작성할 수 있을 것입니다.
중요한 것은 한 번 정한 컨벤션을 지속적으로 유지하고, 새로운 팀원이 합류했을 때도 쉽게 이해할 수 있도록 문서화하는 것입니다.
위 내용 기반 커서rule
Overview
You MUST follow these naming conventions when generating code. Consistent variable naming significantly improves code readability and maintainability.
1. Boolean Variable Naming (MANDATORY)
Use ONLY these 3 prefixes:
// ✅ Correct Boolean naming
const isLoading = true; // state/property
const hasPermission = false; // ownership/inclusion
const canEdit = true; // ability/permission
// ❌ FORBIDDEN
const shouldUpdate = true; // replace with is or can
const willComplete = false; // predictions are inaccurate
const wasModified = true; // focus on current state
Patterns:
is
+ adjective: state or property (isActive, isVisible, isValid)has
+ noun: ownership or inclusion (hasChildren, hasError, hasData)can
+ verb: ability or permission (canDelete, canAccess, canSubmit)
2. Data Manipulation Function Naming
Data Retrieval
// ✅ Clear distinctions
const getUserData = () => { /* synchronous, immediate return */ };
const fetchUserProfile = async () => { /* asynchronous, API call */ };
const loadDashboard = () => { /* loading with UI changes */ };
Data Modification/Manipulation
// ✅ Correct verb usage
const setUser = (user) => { /* complete replacement */ };
const updateProfile = (changes) => { /* partial modification */ };
const addToCart = (item) => { /* add new item */ };
const removeFromCart = (itemId) => { /* remove specific item */ };
const deleteAccount = () => { /* permanent deletion */ };
const clearHistory = () => { /* clear everything */ };
3. Conditional and Filtering Naming
// ✅ Clear conditional expressions
const productsByCategory = filterProducts('category', 'electronics');
const ordersFromLastWeek = getOrders({ startDate: lastWeek });
const emailsToAdmin = messages.filter(msg => msg.recipient === 'admin');
const scoresAboveAverage = scores.filter(score => score > average);
Patterns:
by
+ criteria: grouping criteriafrom
+ source/timepoint: starting point or sourceto
+ target: destination or targetabove
/below
+ reference: comparison conditions
4. Collection Type Specification
// ✅ Clearly express data structures
const userArray = [user1, user2, user3];
const categoryMap = new Map([['id1', 'Electronics']]);
const uniqueTagsSet = new Set(['react', 'javascript']);
const taskQueue = new Queue();
const navigationStack = [];
const menuTree = { name: 'root', children: [] };
const socialGraph = { nodes: [], edges: [] };
Available suffixes:
Array
: general arraysMap
: key-value pair structureSet
: unique value collectionQueue
: first-in-first-out structureStack
: last-in-first-out structureTree
: hierarchical structureGraph
: network structure
5. State Management Naming
// ✅ Specify state types
const connectionStatus = 'connected'; // current state value
const applicationState = { user, cart, preferences }; // state object
const editMode = true; // operation mode
const userType = 'premium'; // classification/type
6. Time-Related Naming
// ✅ Clearly express time relationships
const startTime = new Date();
const endDate = '2024-12-31';
const lastLogin = user.lastLoginAt;
const nextUpdate = calculateNextUpdate();
const currentUser = getCurrentUser();
const previousPage = history.back();
7. Event Handler Naming
// ✅ Event handling patterns
const onClick = (event) => { /* event handler */ };
const handleFormSubmit = (data) => { /* processing function */ };
const beforeSave = () => { /* pre-processing */ };
const afterLoad = () => { /* post-processing */ };
const whenReady = () => { /* conditional execution */ };
8. Utility Function Naming
// ✅ Clear action expression
const formatCurrency = (amount) => `$${amount}`;
const parseUserInput = (input) => JSON.parse(input);
const validateEmail = (email) => /\S+@\S+\.\S+/.test(email);
const convertToString = (value) => String(value);
const buildApiUrl = (endpoint) => `${baseUrl}/${endpoint}`;
9. API/Network Naming
// ✅ Specify network operations
const requestUserData = async (id) => { /* API request */ };
const handleApiResponse = (response) => { /* response handling */ };
const callAuthService = () => { /* service call */ };
const sendAnalytics = (data) => { /* data transmission */ };
const uploadProfileImage = (file) => { /* file upload */ };
const downloadReport = (id) => { /* file download */ };
const syncUserPreferences = () => { /* synchronization */ };
10. Performance Optimization Naming
// ✅ Specify performance-related elements
const userCache = new Map();
const imageBuffer = new ArrayBuffer(1024);
const connectionPool = createPool();
const lazyLoadComponent = () => import('./Component');
const preloadNextPage = () => { /* preloading */ };
11. Error Handling Naming
// ✅ Clearly express error situations
const validationError = new Error('Invalid input');
const maxRetryAttempts = 3;
const fallbackUserData = { name: 'Guest' };
const handleNetworkError = (error) => { /* error handling */ };
12. Security-Related Naming
// ✅ Specify security elements (use environment variables for actual values)
const authToken = process.env.AUTH_TOKEN;
const userPermissions = ['read', 'write'];
const adminRole = 'administrator';
const secureConnection = createSecureConnection();
MANDATORY RULES (Cursor MUST follow)
- Boolean variables MUST start with
is
,has
,can
ONLY - Data retrieval: distinguish
get
(sync),fetch
(API),load
(with UI) - Arrays/collections MUST use type suffixes (
Array
,Map
,Set
, etc.) - Event handlers MUST start with
on
orhandle
- Time-related variables MUST use
start
,end
,current
,last
,next
- Conditional data MUST use
by
,from
,to
,above
patterns
FORBIDDEN PRACTICES
- ❌ Ambiguous Boolean prefixes like
should
,will
,was
- ❌ Generic variable names like
data
,info
,item
- ❌ Abbreviations or shortened forms (e.g.,
usr
instead ofuser
) - ❌ Hungarian notation (e.g.,
strName
,intCount
) - ❌ Collections without clear type (e.g.,
users
instead ofuserArray
)
Example: Complete Component
// ✅ Correct naming convention applied
const UserProfile = () => {
const [isLoading, setIsLoading] = useState(false);
const [hasError, setHasError] = useState(false);
const [canEdit, setCanEdit] = useState(false);
const userPermissions = useUserPermissions();
const profileDataCache = useMemo(() => new Map(), []);
const fetchUserProfile = async (userId) => {
setIsLoading(true);
try {
const userData = await requestUserData(userId);
return userData;
} catch (validationError) {
setHasError(true);
return fallbackUserData;
} finally {
setIsLoading(false);
}
};
const handleFormSubmit = (formData) => {
if (canEdit && validateUserInput(formData)) {
updateUserProfile(formData);
}
};
return (
<div>
{isLoading && <LoadingSpinner />}
{hasError && <ErrorMessage />}
<form onSubmit={handleFormSubmit}>
{/* form content */}
</form>
</div>
);
};
You MUST strictly adhere to these rules to generate consistent and readable code.