Trong bối cảnh phát triển phần mềm toàn cầu hóa mạnh mẽ tại năm 2026, việc tuân thủ các quy chuẩn đặt tên (naming conventions) không chỉ giúp code “sạch” mà còn là yếu tố then chốt quyết định đến khả năng bảo trì, mở rộng và hợp tác trong các đội ngũ đa quốc gia. Đối với các lập trình viên làm việc tại Nhật Bản, làm việc với khách hàng Nhật, hoặc đơn giản là muốn hiểu sâu hơn về văn hóa lập trình đặc trưng của “Xứ sở Hoa Anh Đào”, việc nắm vững tên hằng trong tiếng Nhật (定数の命名規則 – Teisū no Meimei Kisoku) là bắt buộc.

Bài viết này sẽ đi sâu phân tích mọi khía cạnh: từ chuẩn ngữ pháp tiếng Anh phổ biến (SCREAMING_SNAKE_CASE), cách xử lý các từ vựng Nhật (Romaji/Kanji), sự khác biệt giữa const, final, static/readonly trên các ngôn ngữ phổ biến (Java, C#, Python, JavaScript/TypeScript, Go, Rust), cho đến các anti-patterns cần tránh và công cụ hỗ trợ (Linter/Formatter) cập nhật nhất năm 2026.

Phần 1: Cơ Sở Lý Thuyết – “Hằng” Là Gì Và Tại Sao Tên Gọi Quan Trọng?

1.1. Định Nghĩa Kỹ Thuật

Trong khoa học máy tính, hằng số (Constant) là một giá trị không thay đổi được trong quá trình thực thi chương trình sau khi đã được khởi tạo. Khác với biến (Variable), bộ nhớ dành cho hằng thường được tối ưu hóa bởi compiler (nạp thẳng giá trị vào bytecode/machine code, hoặc đặt vào đoạn .rodata read-only memory).

1.2. Vai Trò Của Tên Gọi (Identifier)

Tên hằng không chỉ là nhãn định danh. Nó truyền tải ý định (Intent), phạm vi (Scope) và loại dữ liệu (Semantic Type).

  • Intent: MAX_RETRY_COUNT cho biết đây là giới hạn tối đa, không phải giá trị hiện tại.
  • Scope: PRIVATE_API_KEY vs PUBLIC_CONFIG_VERSION.
  • Type Safety: Trong các ngôn ngữ tĩnh (Java, C#, TypeScript), tên hằng thường gợi nhớ kiểu dữ liệu (ví dụ: suffix _MS cho milliseconds, _BYTES cho dung lượng).

1.3. Chuẩn Quốc Tế: SCREAMING_SNAKE_CASE

Gần như mọi hướng dẫn phong cách (Style Guide) lớn năm 2026 (Google Java Style, Microsoft C# Coding Conventions, PEP 8 Python, Rust API Guidelines, Go Code Review Comments) đều thống nhất một điểm: Tên hằng phải viết HOA toàn bộ, các từ cách nhau bằng dấu gạch dưới (_).

Ví dụ chuẩn quốc tế:
java
// Java / C# / TypeScript / Go / Rust
public static final int DEFAULT_TIMEOUT_MS = 5000;
const string DATABASE_CONNECTION_STRING = "...";
const int MAX_CONCURRENT_USERS = 1000;

Phần 2: Đặc Thù Văn Hóa Lập Trình Nhật Bản (Japanese SIer Culture)

Nhật Bản có ngành công nghiệp phần mềm (SIer – System Integrator) cực lớn với quy trình làm việc rất riêng (Waterfall重, tài liệu hóa kỹ lưỡng, kiểm soát chất lượng cao). Điều này ảnh hưởng trực tiếp đến cách đặt tên hằng.

2.1. Triết Lý “Rõ Ràng Hơn Ngắn Gọn” (明確さ > 簡潔さ)

Khác với xu hướng Westen (Google, Facebook) ưu tiên tên ngắn gọn (MAX_RETRY), các công ty Nhật (Fujitsu, NTT Data, Hitachi, NEC, Rakuten, LINE…) thường ưu tiên tên mô tả đầy đủ ý nghĩa nghiệp vụ (Business Meaning).

Tên Hằng Trong Tiếng Nhật
Tên Hằng Trong Tiếng Nhật

So sánh:
Phong cách Quốc tế: MAX_RETRY = 3
Phong cách Nhật (SIer truyền thống): MAXIMUM_RETRY_ATTEMPT_COUNT = 3 hoặc thậm chí SYSTEM_CONFIG_MAXIMUM_RETRY_ATTEMPT_COUNT = 3

Lý do: Code ở Nhật thường được đọc bởi nhiều người: Developer, Tester, SE (System Engineer – người viết thiết kế), PG (Programmer – người code), thậm chí là khách hàng (User side). Tên dài giảm thiểu sự mơ hồ khi đọc tài liệu thiết kế (詳細設計書 – Detailed Design Doc) mà không cần mở code.

2.2. Vấn Đề Ngôn Ngữ: Tiếng Anh vs Tiếng Nhật (Romaji/Kanji)

Đây là điểm gây tranh cãi và nhầm lẫn nhiều nhất.

A. Chuẩn Mực Năm 2026: Tiếng Anh là bắt buộc (Mandatory English)

Tất cả các Style Guide hiện đại của các tập đoàn lớn tại Nhật (LINE Engineering, Mercari, CyberAgent, Preferred Networks, Sony, Toyota Connected) bắt buộc tên biến, tên hằng, tên hàm, tên class phải bằng tiếng Anh.

  • Lý do: Hỗ trợ offshore (Việt Nam, Ấn Độ, Trung Quốc), thư viện mã nguồn mở (OSS), tooling (IDE, AI Copilot, Static Analysis) hoạt động tốt nhất với ASCII/English.

B. Legacy & Các Dự Án Nội Bộ (Closed System): Romaji/Kanji

Tuy nhiên, trong thực tế năm 2026, bạn vẫn sẽ gặp code dùng tiếng Nhật trong tên hằng ở:

  1. Hệ thống Core Banking, Hệ thống chính phủ (e-Gov), Hệ thống y tế (電子カルテ) – chạy mainframe/COBOL/Java cũ 15-20 năm.
  2. Dự án nội bộ nhỏ, team 100% người Nhật, không có kế hoạch mở rộng quốc tế.
  3. Các hằng số đại diện cho Master Data (マスタデータ) cố định của nghiệp vụ Nhật (Ví dụ: Mã prefecture, Mã thuế, Loại hóa đơn).

C. Cách Xử Lý Romaji (Nếu BẮT BUỘC phải dùng)

Nếu dự án quy định dùng Romaji (thường là Hepburn-shiki), hãy tuân thủ nghiêm ngặt:

  1. Viết HOA toàn bộ: SHOHIN_MEI (商品名 – Tên sản phẩm), ZEI_RITSU (税率 – Thuế suất).
  2. Xử lý âm dài (Long vowels):
    • Ou -> OU (標準 -> HYOJUN).
    • Ei -> EI (先生 -> SENSEI).
    • Kanji đọc Kun-yomi thường không dùng cho hằng hệ thống.
  3. Tách từ bằng _: SHOHIN_KAKAKU (商品価格), NYUKA_BI (入荷日).
  4. Tuyệt đối KHÔNG dùng Kunrei-shiki (ví dụ: TYO cho Tokyo, SYOUHIN cho Shouhin) – đã lỗi thời và gây nhầm lẫn quốc tế.

Ví dụ Romaji chuẩn Hepburn (Khuyến nghị nếu ép buộc):
java
// Master Data Constants
public static final String TODOFUKEN_CODE_TOKYO = "13"; // 都道府県コード_東京
public static final BigDecimal SHOHIZEI_RITSU_10 = new BigDecimal("0.10"); // 消費税率_10%
public static final String SHOHIN_KUBUN_SHOHIN = "01"; // 商品区分_商品
public static final String SHOHIN_KUBUN_SERVICE = "02"; // 商品区分_サービス

D. Tuyệt Đối Không Dùng Kanji/Hiragana/Katakana Trong Identifier

// ❌ TUYỆT ĐỐI KHÔNG LÀM NHƯ THẾ NÀY (Dù Java/C#/Python 3 hỗ trợ Unicode Identifier)
public static final int 最大リトライ回数 = 3; const string 接続文字列 = "...";
let MAX_リトライ = 5; // Camp 섞어 쓰기 - 混在 (Kon-zai) - Rất tệ

Lý do: Khó search (grep), khó review trên terminal/SSH, lỗi encoding, AI Copilot hiểu sai, teammate nước ngoài không đọc được.

Phần 3: Quy Tắc Chi Tiết Theo Ngôn Ngữ Lập Trình (Cập Nhật 2026)

Mặc dù chuẩn chung là SCREAMING_SNAKE_CASE, nhưng từng ngôn ngữ có “cá tính” riêng về từ khóa khai báo và phạm vi.

3.1. Java (JDK 21 LTS / JDK 24 năm 2026)

  • Từ khóa: static final (cho class/instance constants), final (cho local constants).
  • Interface constants: Mặc định public static final -> Viết HOA.
  • Enum: Các hằng enum (INSTANCE) viết HOA. Các field trong enum viết HOA.
  • Record (Java 16+): Các component không phải hằng, nhưng static final field trong record viết HOA.
public class AppConfig { // Class-level constant (Global config) public static final int DEFAULT_PAGE_SIZE = 20; public static final Duration SESSION_TTL = Duration.ofHours(24); // Private internal constant private static final String INTERNAL_CACHE_PREFIX = "app:v1:"; // Local constant (trong method) -> Cũng viết HOA theo Google Java Style public void process() { final int MAX_LOOP_COUNT = 100; // ... }
} // Enum - Best practice cho nhóm hằng liên quan
public enum HttpStatus { OK(200, "OK"), NOT_FOUND(404, "Not Found"), INTERNAL_SERVER_ERROR(500, "Internal Server Error"); private final int code; private final String message; HttpStatus(int code, String message) { ... }
}

Lưu ý 2026: Sử dụng Duration, Instant, Period thay vì long timeoutMs để type-safe. Tên hằng nên có hậu tố đơn vị: _MS, _SECONDS, _BYTES, _KB.

3.2. C# / .NET (C# 12 / .NET 8 LTS / .NET 9 năm 2026)

  • Từ khóa: const (compile-time constant), static readonly (runtime constant), readonly (instance constant).
  • Quy tắc Microsoft: const và static readonly public/protected -> PascalCase (Khác Java!).
  • Private/Internal: SCREAMING_SNAKE_CASE hoặc _pascalCase (tùy team, nhưng Microsoft khuyến nghị PascalCase cho tất cả static readonly public).
public class AppSettings
{ // const: Compile-time, giá trị phải là literal/const expression -> PascalCase public const int DefaultPageSize = 20; public const string ApiVersion = "v1"; // static readonly: Runtime, có thể new object, config -> PascalCase (Chuẩn Microsoft) public static readonly TimeSpan SessionTtl = TimeSpan.FromHours(24); public static readonly ImmutableArray<string> AllowedOrigins = ImmutableArray.Create("https://example.com", "https://admin.example.com"); // Private constants -> Thường dùng _camelCase hoặc SCREAMING_SNAKE_CASE tùy team // Microsoft internal style thường dùng _camelCase cho private static readonly private static readonly ILogger _logger = LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger<AppSettings>(); // Local const -> PascalCase public void Process() { const int MaxRetryCount = 3; }
}

Cạm bẫy lớn năm 2026: Nhiều dev Java chuyển sang C# vẫn viết SCREAMING_SNAKE_CASE cho public static readonly. Điều này vi phạm Microsoft Coding Conventions và làm cho code C# trông “không native”. Hãy dùng PascalCase cho public constants trong C#.

3.3. Python (Python 3.12 / 3.13 năm 2026)

  • PEP 8: Constants at module level -> SCREAMING_SNAKE_CASE.
  • Class/Instance constants: Python không có const thật sự. Quy ước: Viết HOA để báo hiệu “Đừng sửa”.
  • typing.Final (Python 3.8+): Dùng cho type checker (mypy, pyright).
# constants.py (Module level)
DEFAULT_PAGE_SIZE = 20
MAX_RETRY_COUNT = 3
API_BASE_URL = "https://api.example.com/v1"
DATABASE_CONNECTION_POOL_SIZE = 10 # Sử dụng typing.Final để tĩnh kiểm tra
from typing import Final class Config: # Class-level "constants" SESSION_TTL_SECONDS: Finalint = 86400 def __init__(self): # Instance "constant" (read-only property pattern is better) self._api_key: Finalstr = os.getenv("API_KEY") # Enum (Python 3.4+)
from enum import Enum, auto class UserRole(Enum): ADMIN = auto() USER = auto() GUEST = auto()

Best Practice 2026: Dùng pydantic-settings (BaseSettings) để quản lý config từ env var, các field trong class Settings thường dùng SCREAMING_SNAKE_CASE mapping từ env.

3.4. JavaScript / TypeScript (ES2024 / TS 5.4+ năm 2026)

  • const keyword: Bắt buộc dùng const thay var/let cho mọi binding không gán lại.
  • Naming Convention:
    • Module-level true constants (Primitive/Object.freeze): SCREAMING_SNAKE_CASE.
    • Configuration Objects / Class static properties: Thường dùng PascalCase hoặc camelCase tùy framework (React, Vue, Angular, NestJS).
    • TypeScript readonly / const assertions (as const): Rất quan trọng năm 2026.
// constants.ts
// True primitives constants -> SCREAMING_SNAKE_CASE
export const MAX_FILE_SIZE_BYTES = 10 1024 1024; // 10MB
export const DEFAULT_LANG = "ja-JP" as const; // Literal type narrowing
export const SUPPORTED_LANGS = "ja-JP", "en-US", "zh-CN" as const; // Readonly tuple // Configuration Object -> PascalCase (React/Next.js/NestJS style)
export const AppConfig = { apiEndpoint: "https://api.example.com", timeoutMs: 5000,
} as const; // Deep readonly // Class static readonly -> PascalCase (Angular/NestJS style)
@Injectable()
export class AuthService { static readonly TOKEN_HEADER = "X-Auth-Token"; static readonly DEFAULT_SCOPES = "read", "write" as const; // Instance readonly private readonly _httpClient: HttpClient;
}

Xu hướng 2026: as const là chuẩn vàng để suy diễn kiểu literal (Literal Types), giúp type-safe cực mạnh cho Redux, React Context, tRPC, Zod schemas.

Tên Hằng Trong Tiếng Nhật
Tên Hằng Trong Tiếng Nhật

3.5. Go (Go 1.22 / 1.23 năm 2026)

  • Không có const cho struct/array/slice/map (chỉ có cho primitive: number, string, boolean, rune).
  • Quy tắc: SCREAMING_SNAKE_CASE cho package-level constants. PascalCase cho exported constants (public), camelCase hoặc SCREAMING_SNAKE_CASE cho unexported (private).
  • iota: Dùng cho enum-like constants.
package config import "time" // Exported (Public) -> PascalCase (Go Standard)
const ( DefaultPageSize = 20 MaxRetryCount = 3 ApiVersion = "v1"
) // Unexported (Private) -> camelCase hoặc SCREAMING_SNAKE_CASE (Team decision)
// Go community thường thích camelCase cho private const để nhất quán với variable.
const ( defaultTimeout = 5 time.Second internalCachePrefix = "app:v1:"
) // Iota for Enum-like
type UserRole int const ( RoleGuest UserRole = iota // 0 RoleUser // 1 RoleAdmin // 2
) // String() method cho log đẹp
func (r UserRole) String() string { return ...string{"GUEST", "USER", "ADMIN"}r
}

Lưu ý: Go không khuyến khích SCREAMING_SNAKE_CASE cho exported identifiers (public). Nó trông “khá lạ” trong Go codebase. Hãy dùng PascalCase.

3.6. Rust (Rust 2021 Edition / 2024 Edition năm 2026)

  • const vs static:
    • const: Inline tại chỗ sử dụng (compile time), không có địa chỉ bộ nhớ cố định. Luôn SCREAMING_SNAKE_CASE.
    • static: Có địa chỉ bộ nhớ cố định (‘static lifetime), có thể mutable (static mut – unsafe). Luôn SCREAMING_SNAKE_CASE.
  • Trait/Enum variants: PascalCase (Enum variants) / SCREAMING_SNAKE_CASE (Const items trong trait).
// constants.rs
// const: Compile-time evaluated, inlined
const DEFAULT_PAGE_SIZE: usize = 20;
const MAX_RETRY_COUNT: u32 = 3;
const API_VERSION: &str = "v1"; // static: Fixed memory address, can be referenced
static SESSION_TTL: std::time::Duration = std::time::Duration::from_secs(86400);
// static mut is discouraged in 2026, use AtomicUsize / Mutex / OnceLock instead
static REQUEST_COUNTER: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); // Enum variants -> PascalCase
#derive(Debug, Clone, Copy, PartialEq, Eq)
pub enum HttpStatus { Ok = 200, NotFound = 404, InternalServerError = 500,
} // Const generics (Rust 2024 feature) - name usually generic like N, M or descriptive
fn process_buffer<const BUFFER_SIZE: usize>(data: &u8) { ... }

Phần 4: Phân Loại Hằng Theo Nghiệp Vụ (Domain-Driven Constants)

Năm 2026, việc gom tất cả hằng vào file Constants.java/constants.ts/constants.go được coi là Anti-pattern (God Class). Hãy phân loại và đặt tên theo ngữ cảnh (Context).

4.1. Configuration Constants (Cấu Hình Hệ Thống)

  • Scope: Application-wide, có thể thay đổi giữa env (dev/stg/prod) -> Nên externalize ra config file (YAML/JSON/Env Var), không hardcode.
  • Naming: APP_<DOMAIN>_<ACTION>_<UNIT>
  • Ví dụ:
    • APP_HTTP_CLIENT_TIMEOUT_MS
    • APP_DB_CONNECTION_POOL_MAX_SIZE
    • APP_CACHE_TTL_SECONDS
    • APP_FEATURE_FLAG_NEW_UI_ENABLED

4.2. Business Rule Constants (Quy Tắc Nghiệp Vụ – Domain Logic)

  • Scope: Bên trong Domain Layer (DDD). Không bao giờ thay đổi trừ khi luật pháp/quy trình thay đổi.
  • Naming: <ENTITY>_<RULE>_<UNIT> hoặc <VALUE_OBJECT>_<CONSTRAINT>
  • Ví dụ (E-commerce Nhật):
    • ORDER_MAX_ITEMS_PER_CART = 50
    • ORDER_CANCEL_WINDOW_MINUTES = 30
    • PRODUCT_PRICE_TAX_RATE_PERCENT = 10 (消費税率 10%)
    • SHIPPING_FREE_THRESHOLD_YEN = 5000
    • POINT_EXPIRATION_MONTHS = 12
    • INVOICE_REGISTRATION_NUMBER_PREFIX = "T" (Định danh hóa đơn điện tử 適格請求書発行事業者登録番号)

4.3. Technical / Infrastructure Constants (Kỹ Thuật / Hạ Tầng)

  • Scope: Framework, Library, Middleware integration.
  • Naming: <TECH>_<COMPONENT>_<PARAM>
  • Ví dụ:
    • KAFKA_PRODUCER_ACKS_ALL = "all"
    • REDIS_CLUSTER_MAX_REDIRECTIONS = 16
    • POSTGRES_STATEMENT_TIMEOUT_MS = 30000
    • AWS_S3_MULTIPART_UPLOAD_THRESHOLD_BYTES = 52428800 (50MB)

4.4. Master Data / Code Values (マスタデータ / コード値)

  • Đặc thù Nhật Bản: Hệ thống Nhật dùng rất nhiều “Code Table” (区分マスタ – Kubun Master). Ví dụ: 性別区分 (Gender Code: 1:男, 2:女, 9:不明), 削除フラグ (Delete Flag: 0:有効, 1:削除).
  • Cách đặt tên năm 2026: Đừng hardcode số liệu (Magic Numbers). Hãy dùng Enum hoặc Class chứa hằng.
  • Naming Pattern: <MASTER_NAME>_<COLUMN>_<VALUE_MEANING>
// ❌ Magic Number - Cấm tuyệt đối
if (user.getSexKbn() == 1) { ... }
if (order.getDeleteFlag() == 0) { ... } // ✅ Enum / Constant Class - Chuẩn 2026
public class MasterConstants { // 性別区分 (Seibetsu Kubun) public static final String SEIBETSU_KUBUN_MALE = "1"; public static final String SEIBETSU_KUBUN_FEMALE = "2"; public static final String SEIBETSU_KUBUN_UNKNOWN = "9"; // 削除フラグ (Sakujo Flag) public static final String SAKUJO_FLAG_ACTIVE = "0"; public static final String SAKUJO_FLAG_DELETED = "1"; // 消費税区分 (Shohizei Kubun) - Japanese Tax Codes public static final String SHOHIZEI_KUBUN_TAXABLE_10 = "1"; // 課税10% public static final String SHOHIZEI_KUBUN_TAXABLE_8 = "2"; // 課税8% (軽減税率) public static final String SHOHIZEI_KUBUN_NON_TAXABLE = "3"; // 非課税 public static final String SHOHIZEI_KUBUN_TAX_FREE = "4"; // 免税
}

Pro Tip 2026: Dùng Java enum with fields hoặc TypeScript const object as const để mapping cả Code, Label (日本語名), và Logic (ví dụ: tính thuế).

// Java Enum Rich Model - Best Practice cho Master Data Nhật
public enum ShohizeiKubun { TAXABLE_10("1", "課税10%", BigDecimal.valueOf(0.10)), TAXABLE_8 ("2", "課税8%", BigDecimal.valueOf(0.08)), // 減税率 NON_TAXABLE("3", "非課税", BigDecimal.ZERO), TAX_FREE ("4", "免税", BigDecimal.ZERO); private final String code; private final String labelJa; private final BigDecimal rate; ShohizeiKubun(String code, String labelJa, BigDecimal rate) { ... } public static ShohizeiKubun ofCode(String code) { ... } public BigDecimal calculateTax(BigDecimal amount) { return amount.multiply(rate).setScale(0, RoundingMode.HALF_UP); }
}

4.5. API Contract Constants (API インターフェース定義)

  • Dùng cho Header names, Query param keys, Error codes.
  • Naming: HEADER_<NAME>, PARAM_<NAME>, ERROR_CODE_<DOMAIN>_<REASON>
// api-constants.ts
export const API_HEADERS = { AUTHORIZATION: "Authorization", IDEMPOTENCY_KEY: "Idempotency-Key", // Quan trọng cho API thanh toán Nhật REQUEST_ID: "X-Request-Id", CONTENT_TYPE: "Content-Type",
} as const; export const ERROR_CODES = { VALIDATION_FAILED: "ERR_VALIDATION_FAILED", INSUFFICIENT_BALANCE: "ERR_PAYMENT_INSUFFICIENT_BALANCE", CONCURRENCY_CONFLICT: "ERR_CONCURRENCY_CONFLICT", // Mã lỗi nghiệp vụ Nhật thường có prefix hệ thống SYSTEM_MAINTENANCE: "ERR_SYS_001", } as const;

Phần 5: Xử Lý Đơn Vị Đo Lường (Units) – Yếu Tố Sinh Tử

Năm 2026, với sự phổ biến của Observability (Metrics, Tracing, Logging) và FinOps (Chi phí Cloud), việc nhầm lẫn đơn vị (ms vs s, bytes vs MB) gây ra sự cố production nghiêm trọng (Outage, Cost spike).

5.1. Quy Tắc Bắt Buộc: Suffix Đơn Vị Luôn Có Mặt

Tên Hằng Trong Tiếng Nhật
Tên Hằng Trong Tiếng Nhật

Tên hằng bắt buộc chứa đơn vị ở cuối tên (Suffix) nếu nó đại diện cho lượng vật lý hoặc thời gian.

Sai (Dangerous) Đúng (Safe) Giải Thích
TIMEOUT = 5000 TIMEOUT_MS = 5000 5000 giây hay 5000 ms?
MAX_SIZE = 100 MAX_SIZE_BYTES = 100 100 bytes? KB? MB?
RETRY_DELAY = 2 RETRY_DELAY_SECONDS = 2 2ms? 2s? 2 phút?
THREAD_POOL_SIZE = 10 THREAD_POOL_MAX_SIZE = 10 Size là count, không cần unit nhưng cần ngữ cảnh Max/Min/Core.

5.2. Chuẩn Hóa Đơn Vị (SI Units & Common Tech Units)

  • Thời gian: _NANOS, _MICROS, _MILLIS / _MS, _SECONDS / _SEC, _MINUTES / _MIN, _HOURS / _HR, _DAYS.
    • Khuyến nghị: Ưu tiên _MS (milliseconds) cho timeout/network, _SECONDS cho TTL/cache.
  • Dung lượng: _BYTES, _KB, _MB, _GB, _TB. (Lưu ý: 1KB = 1024 bytes trong CS context, nhưng 1000 trong SI. Khuyên dùng _BYTES cho chính xác).
  • Tốc độ: _PER_SECOND (RPS, TPS), _MBPS, _GBPS.
  • Tỷ lệ/Phần trăm: _PERCENT (giá trị 0-100), _RATIO (giá trị 0.0-1.0), _BPS (Basis Points – 1/10000, dùng trong tài chính).
  • Số lượng: _COUNT, _SIZE, _LENGTH, _CAPACITY, _LIMIT.

5.3. Sử Dụng Type System Thay Vì Suffix (Modern Approach 2026)

Thay vì chỉ dựa vào tên, hãy dùng Strong Types (Wrapper Types / Value Objects).

Java (Project Valhalla / Records / Libraries):

// Dùng Duration/Instant (JDK 8+) thay vì long + suffix
public static final Duration REQUEST_TIMEOUT = Duration.ofMillis(5000);
public static final Duration CACHE_TTL = Duration.ofHours(24); // Custom Value Object cho Byte Size (hoặc dùng library như Google Common/Apache Commons)
public record ByteSize(long bytes) { public static ByteSize ofMegabytes(long mb) { return new ByteSize(mb 1024 1024); } public long toBytes() { return bytes; }
}
public static final ByteSize MAX_UPLOAD_SIZE = ByteSize.ofMegabytes(100);

TypeScript (Branded Types / Zod / Effect):

// Branded Types cho Type Safety tại compile time
type Milliseconds = number & { readonly _brand: unique symbol };
type Bytes = number & { readonly _brand: unique symbol }; const toMs = (ms: number): Milliseconds => ms as Milliseconds;
const toBytes = (b: number): Bytes => b as Bytes; export const TIMEOUT: Milliseconds = toMs(5000);
export const MAX_PAYLOAD: Bytes = toBytes(10 1024 1024); // Usage: function fetch(config: { timeout: Milliseconds }) { ... }
// fetch({ timeout: 5000 }) // ❌ Type Error: number != Milliseconds
// fetch({ timeout: TIMEOUT }) // ✅ OK

Rust (Newtype Pattern / std::time::Duration):

use std::time::Duration; // Standard library types
pub const REQUEST_TIMEOUT: Duration = Duration::from_millis(5000); // Newtype for domain specific units (e.g., Yen, BasisPoints)
#derive(Debug, Clone, Copy, PartialEq, Eq)
pub struct Yen(pub i64); // Wrapper type pub const MIN_TRANSFER_AMOUNT: Yen = Yen(100); // 100 Yen
pub const TAX_RATE_BPS: u32 = 1000; // 10.00% = 1000 bps

Phần 6: Anti-Patterns & Code Smells (Các Mẫu Xấu Cần Tránh Năm 2026)

6.1. “Constants Interface” Antipattern (Java/C#)

// ❌ CŨ TECH (Java 1.0 style) - ĐỪNG LÀM NỮA
public interface Constants { String DB_URL = "jdbc:..."; int MAX_SIZE = 100;
}
public class MyService implements Constants { // Kế thừa interface chỉ để dùng constant? Sai OOP. void doSomething() { System.out.println(MAX_SIZE); }
}
  • Sửa: Dùng final class Constants { private Constants() {} ... } (Utility class) hoặc enum hoặc static import.

6.2. “God Constants Class” / “Util Dumping Ground”

// ❌ File Constants.java 5000 dòng chứa mọi thứ: DB, UI, Business, Tax, Email, Regex...
public class Constants { ... }
  • Sửa: Tách theo Module/Domain/Package.
    • com.company.project.config.AppConstants (System config)
    • com.company.project.order.domain.OrderConstants (Business rules)
    • com.company.project.infra.db.DbConstants (SQL queries, table names)
    • com.company.project.common.tax.TaxConstants (Tax logic)

6.3. Magic Numbers/String Literals Nổi Loạn

// ❌
if (status == 1) { ... }
url = "https://api.example.com/v1/users";
threadPool.setCorePoolSize(10);
  • Sửa: Extract ngay lập tức (IDE Refactor: Extract Constant). Даже nếu chỉ dùng 1 lần, nếu có ý nghĩa nghiệp vụ -> Hằng.

6.4. Đặt Tên Quá Chung Chung (Ambiguous Names)

// ❌
const int MAX = 100; // Max của cái gì? User? Retry? File size?
const string KEY = "id"; // Key của cache? DB? JWT? Header?
const int TIMEOUT = 30; // 30 giây? 30 phút?
  • Sửa: MAX_RETRY_ATTEMPTS, CACHE_KEY_USER_ID, DB_QUERY_TIMEOUT_SECONDS.

6.5. Lạm Dụng public static final Cho Object Mutable

// ❌ NGUY HIỂM - Mutable Object Escape
public static final List<String> ALLOWED_IPS = new ArrayList<>(List.of("127.0.0.1"));
// Ai đó có thể làm: Constants.ALLOWED_IPS.add("evil.com"); -> BUG TOÀN CỤC
  • Sửa: Dùng Immutable Collections (Java: List.of, Set.of, Map.of, Guava ImmutableList; C#: ImmutableArray, FrozenSet; TS: as const, ReadonlyArray; Rust: &'static T, LazyLock).
// ✅ AN TOÀN
public static final List<String> ALLOWED_IPS = List.of("127.0.0.1", "10.0.0.0/8"); // Java 9+
// Hoặc
public static final Set<String> ALLOWED_IPS = Set.of("127.0.0.1");

6.6. Hardcode Secrets/Credentials Dưới Dạng Hằng

// ❌ TUYỆT ĐỐI KHÔNG - SECURITY VIOLATION
public static final String AWS_SECRET_KEY = "AKIAIOSFODNN7EXAMPLE";
public static final String DB_PASSWORD = "P@ssw0rd2026";
  • Chuẩn 2026: Secrets KHÔNG BAO GIỜ nằm trong code (Constants hay Config file commit git). Dùng: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Kubernetes Secrets, SOPS, 1Password CLI. Code chỉ giữ tên key: SECRET_KEY_AWS_SECRET_ACCESS_KEY.

Phần 7: Tooling & Enforcement Năm 2026 (Automation First)

Đừng nhờ review thủ công. Hãy bắt máy móc làm việc.

7.1. Linter / Static Analysis Rules

Ngôn Ngữ Tool 2026 Rule Key (Ví dụ) Cấu Hình Khuyến Nghị
Java SpotBugs, PMD, Checkstyle, SonarQube/Cloud ConstantName (Checkstyle), UuFUnusedField (SpotBugs) format = ^A-ZA-Z0-9(_A-Z0-9+)$
Check static final fields, interface fields, enum constants.
C# Roslyn Analyzers (built-in), SonarAnalyzer.CSharp, StyleCop.Analyzers SA1310 (Field names), CA1707 (Identifiers) Enforce PascalCase cho public const/static readonly. Private: camelCase hoặc _camelCase.
Python Ruff (Thay Flake8/Pylint – Nhanh hơn 100x), Mypy, Pyright PLR0124 (Constant naming), TYC001 (Type checking Final) ruff: select = "PLR", "TYC"
Enforce SCREAMING_SNAKE_CASE cho module-level vars có type Final hoặc all-caps.
JS/TS ESLint (v9+ Flat Config), TypeScript ESLint, Biome (Rust-based, super fast) @typescript-eslint/naming-convention Config phức tạp: const variable -> UPPER_CASE (nếu primitive/object.freeze), PascalCase (nếu config object/class). readonly property -> PascalCase.
Go golangci-lint (v1.60+), staticcheck, go vet golint (exported const), staticcheck (ST1000) Enforce PascalCase cho exported const. camelCase cho unexported.
Rust Clippy (Built-in), Rustfmt upper_case_acronyms, const_naming Mặc định đã enforce SCREAMING_SNAKE_CASE cho const/static. Chỉ cần cargo clippy -- -D warnings.

7.2. Formatter (Code Style Unity)

Tên Hằng Trong Tiếng Nhật
Tên Hằng Trong Tiếng Nhật
  • Java: google-java-format / spotless-maven-plugin / ktlint (Kotlin).
  • C#: dotnet format (built-in), csharpier (Prettier-like).
  • Python: Ruff Format (Built-in, thay Black/Isort).
  • JS/TS: Biome (Formatter + Linter all-in-one, cực nhanh) hoặc Prettier + ESLint.
  • Go: gofmt / gofumpt (Stricter).
  • Rust: rustfmt (Standard).

7.3. Pre-commit / CI Gate (Husky / Lefthook / GitHub Actions / GitLab CI)

# .github/workflows/ci.yml (Snippet)
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Java - name: Checkstyle run: ./mvnw checkstyle:check # TypeScript - name: Biome Check run: npx biome check --apply-unsafe . # Python - name: Ruff Check run: ruff check . && ruff format --check . # Go - name: Golangci-lint uses: golangci/golangci-lint-action@v6 # Rust - name: Clippy & Fmt run: cargo clippy -- -D warnings && cargo fmt --check

Năm 2026: “Fail Fast” tại local (pre-commit hook) và “Gatekeeping” tại CI/CD. Không merge nếu lint fail.

7.4. AI Coding Assistant Context (GitHub Copilot / Cursor / Codeium / Tabnine)

  • Cung cấp file .github/copilot-instructions.md hoặc .cursorrules chứa quy tắc đặt tên hằng của team.
  • Ví dụ instruction: “All constants must use SCREAMING_SNAKE_CASE with unit suffix (e.g., _MS, _BYTES). No magic numbers. Use Duration/ByteSize types where possible.”
  • AI sẽ sinh code đúng chuẩn ngay từ đầu, giảm tải review.

Phần 8: Case Study Thực Tế – Hệ Thống E-Commerce Nhật Bản (2026)

Giả lập một module Order Pricing (Tính giá đơn hàng) tuân thủ luật thuế Nhật (消費税法), xử lý giảm giá (割引 – Waribiki), điểm thưởng (ポイント – Point), phí ship (送料 – Souryou).

8.1. Domain Constants (Business Rules)

package com.example.ec.order.domain.pricing; import java.math.BigDecimal;
import java.time.Duration; / Hằng số nghiệp vụ định giá đơn hàng. Tuân thủ: Luật tiêu biểu giá tổng hợp (総額表示義務), Giảm thuế nhẹ (軽減税率 8%). /
public final class PricingConstants { private PricingConstants() {} // Utility class // --- Tax (消費税) --- / Thuế tiêu chuẩn 10% (標準税率) / public static final BigDecimal TAX_RATE_STANDARD = BigDecimal.valueOf(0.10); / Thuế giảm nhẹ 8% (軽減税率 - Thực phẩm, báo刊) / public static final BigDecimal TAX_RATE_REDUCED = BigDecimal.valueOf(0.08); / Mã khu vực thuế cho API outside (免税/輸出) / public static final String TAX_EXEMPT_CODE = "EXPORT"; // --- Rounding (端数処理 - Hasuu Shori) --- / Làm tròn: 四捨五入 (Round Half Up) - Chuẩn kế toán Nhật / public static final int TAX_ROUNDING_MODE = java.math.RoundingMode.HALF_UP.ordinal(); // Hoặc dùng Enum RoundingMode / Đơn vị làm tròn tiền tệ: 1 Yen (円単位) / public static final BigDecimal CURRENCY_UNIT = BigDecimal.ONE; // --- Discount (割引 - Waribiki) --- / Tối đa % giảm giá cho 1 dòng sản phẩm (防止不正注文) / public static final int MAX_LINE_DISCOUNT_PERCENT = 50; // 50% / Tối đa số mã voucher áp dụng cho 1 đơn hàng / public static final int MAX_VOUCHER_COUNT_PER_ORDER = 3; / Giá trị tối thiểu đơn hàng để dùng voucher % (円) / public static final long MIN_ORDER_AMOUNT_FOR_PERCENT_VOUCHER_YEN = 1000; // --- Points (ポイント) --- / Tỷ lệ quy đổi: 1 Point = 1 Yen (1ポイント = 1円) / public static final BigDecimal POINT_TO_YEN_RATE = BigDecimal.ONE; / Tối đa % giá trị đơn hàng có thể thanh toán bằng Point (例: 30%) / public static final int MAX_POINT_USAGE_PERCENT = 30; / Hạn sử dụng Point mặc định: 12 tháng (有効期限) / public static final Duration POINT_DEFAULT_VALIDITY = Duration.ofDays(365); // Hoặc 12 months logic // --- Shipping (送料 - Souryou) --- / Miễn phí ship cho đơn từ 5,000 Yen (税込) / public static final long FREE_SHIPPING_THRESHOLD_TAX_INCLUDED_YEN = 5000; / Phí ship cơ bản toàn quốc (円) / public static final long BASE_SHIPPING_FEE_YEN = 600; / Phí ship thêm cho Okinawa/Hokkaido/離島 (Rito - Đảo xa) / public static final long REMOTE_ISLAND_SURCHARGE_YEN = 1500; // --- Calculation Precision (計算精度) --- / Số chữ số thập phân tối đa cho tính toán trung gian (内部計算桁数) / public static final int INTERNAL_CALCULATION_SCALE = 10;
}

8.2. Technical Constants (Infra/Framework)

package com.example.ec.order.infra.config; import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; / Cấu hình kỹ thuật - Được inject từ application.yml / Kubernetes ConfigMap / Vault. KHÔNG hardcode giá trị ở đây, chỉ định义 default/structure. /
@ConfigurationProperties(prefix = "app.order")
@Component
public class OrderTechnicalConfig { // Timeouts (单位: Milliseconds - 接続タイムアウト) public Duration httpClientConnectTimeout = Duration.ofMillis(2000); // 2s public Duration httpClientReadTimeout = Duration.ofMillis(5000); // 5s public Duration paymentGatewayTimeout = Duration.ofSeconds(30); // 30s (外部決済GWは長め) // Retry & Resilience (リトライ・レジリエンス) public int maxRetryAttempts = 3; public Duration retryBackoffBaseDelay = Duration.ofMillis(500); public double retryBackoffMultiplier = 2.0; // Concurrency (並行制御) public int inventoryLockTimeoutSeconds = 10; // DB Row Lock (SELECT FOR UPDATE) public int idempotencyKeyTtlHours = 24; // Redis TTL for Idempotency Key // Batch/Async (バッチ・非同期) public int orderExportBatchChunkSize = 1000; public int asyncEventPublishQueueCapacity = 10000;
}

8.3. Master Data Constants (Code Values)

package com.example.ec.common.master; / Master Data Codes - Ánh xạ từ DB Table: M_KUBUN (区分マスタ). Sử dụng Enum để Type-Safe và gắn logic/label. /
public enum OrderStatusKubun { // Code, Label_JA, Label_EN, IsFinal, SortOrder NEW("10", "新規注文", "New", false, 10), PAYMENT_PENDING("20", "入金待ち", "Payment Pending", false, 20), PAID("30", "入金済み", "Paid", false, 30), PROCESSING("40", "処理中", "Processing", false, 40), SHIPPED("50", "発送済み", "Shipped", false, 50), DELIVERED("60", "配達完了", "Delivered", true, 60), // Final state CANCELLED("90", "キャンセル", "Cancelled", true, 90), // Final state RETURNED("95", "返品完了", "Returned", true, 95); private final String code; private final String labelJa; private final String labelEn; private final boolean finalState; private final int sortOrder; OrderStatusKubun(String code, String labelJa, String labelEn, boolean finalState, int sortOrder) { this.code = code; this.labelJa = labelJa; this.labelEn = labelEn; this.finalState = finalState; this.sortOrder = sortOrder; } // Getters, ofCode(), isFinalState()...
}

Phần 9: Kiểm Thử (Testing) Tên Hằng – Contract Testing

Năm 2026, tên hằng (đặc biệt là API Contract, Error Codes, Event Names) là Giao Diện (Interface). Thay đổi tên hằng = Breaking Change.

9.1. Snapshot Testing cho Constants

// PricingConstantsTest.java
class PricingConstantsTest { @Test void constantsShouldMatchSnapshot() { // Dùng AssertJ / Snapshot testing library // Đảm bảo không ai xóa/sửa tên/giá trị constants vô tình assertThat(PricingConstants.class) .hasFieldOrPropertyWithValue("TAX_RATE_STANDARD", BigDecimal.valueOf(0.10)) .hasFieldOrPropertyWithValue("FREE_SHIPPING_THRESHOLD_TAX_INCLUDED_YEN", 5000L); } @Test void constantNamesShouldFollowConvention() { // Reflection scan all public static final fields // Check regex: ^A-ZA-Z0-9(_A-Z0-9+)$ // Check suffix for units: _YEN, _PERCENT, _MS, _SECONDS, _COUNT }
}

9.2. Consumer-Driven Contract Testing (Pact / Spring Cloud Contract)

  • Nếu ERROR_CODE_INSUFFICIENT_BALANCE đổi thành ERR_BALANCE_LOW -> Consumer (Frontend, Mobile App, Partner API) sẽ break.
  • Test Pact sẽ fail ngay tại CI của Provider trước khi deploy.

Phần 10: Tài Liệu Hóa (Documentation) & Knowledge Sharing

Tên Hằng Trong Tiếng Nhật
Tên Hằng Trong Tiếng Nhật

10.1. JavaDoc / KDoc / Docstring / Rustdoc Chuẩn

Mọi hằng public/exported bắt buộc có tài liệu giải thích:

  1. Ý nghĩa nghiệp vụ: Tại sao giá trị này là 5000? (Ví dụ: “Ngưỡng miễn phí ship theo chính sách Marketing Q3/2026”).
  2. Đơn vị: Nhắc lại đơn vị (_YEN, _MS).
  3. Nguồn gốc: Config file? DB Master? Hardcoded rule? Luật pháp?
  4. Lịch sử thay đổi (Changelog): Khi nào đổi, tại sao, ai duyệt.
/ Ngưỡng miễn phí vận chuyển (送料無料ライン). <p> Áp dụng cho đơn hàng có tổng tiền hàng (税込) >= 5,000 JPY. Dựa trên chính sách Marketing "Free Shipping Campaign 2026-H1". <b>Lưu ý:</b> Không bao gồm phí COD (代引き手数料) hay phí đảo xa (離島手数料). </p> <ul> <li><b>Đơn vị:</b> Yen (円) - Tax Included (税込)</li> <li><b>Nguồn:</b> Config `app.order.free-shipping-threshold` (K8s ConfigMap)</li> <li><b>Lịch sử:</b> 2025: 3,000 -> 2026/04/01: 5,000 (Chiến lược lợi nhuận)</li> </ul> @since 2024.1 @see OrderTechnicalConfig#freeShippingThresholdTaxIncludedYen /
public static final long FREE_SHIPPING_THRESHOLD_TAX_INCLUDED_YEN = 5000L;

10.2. Architecture Decision Records (ADR)

Mọi quyết định quan trọng về Constants (Ví dụ: “Quyết định dùng Duration thay vì long _MS“, “Quyết định tách Master Data ra Enum thay vì String constants”) phải ghi vào ADR (Markdown trong repo docs/adr/).

# ADR 0012: Use Strong Types for Physical Quantities (Time, Money, Size) ## Status: Accepted (2026-01-15) ## Context
Magic numbers with unit suffixes (_MS, _YEN) are error-prone. Refactoring units requires global search/replace. ## Decision
Adopt Value Objects / Strong Types:
- Time: `java.time.Duration` / `std::time::Duration`
- Money: `Joda-Money` / Custom `Yen` record / `rust-decimal::Decimal`
- Size: Custom `ByteSize` record. ## Consequences
- Pros: Compile-time safety, refactoring safety, self-documenting APIs.
- Cons: Slight boilerplate, serialization config needed (Jackson/Serde).

Phần 11: Xu Hướng Tương Lai (2026+) & Kết Luận

11.1. Compile-Time Constants & Configuration as Code

  • C++ consteval / constinit, Rust const evaluation, C# const / static readonly, Java constantdynamic (JDK 11+) / Project Valhalla (Primitive Classes/Value Types).
  • Xu hướng: Push logic vào Compile Time. Constants không chỉ là data, mà là Contract được verify bởi Compiler.

11.2. Configuration Drift Detection

  • Tools như Configu, Chamber, Spring Cloud Config, Consul, etcd kết hợp với GitOps (ArgoCD/Flux).
  • Constants trong code (DEFAULT_TIMEOUT) vs Config Runtime (app.timeout) -> Drift Detection alert ngay nếu lệch.

11.3. AI-Generated Constants & Validation

  • LLM (Copilot, Cursor, Devin) sinh ra constants kèm test, doc, ADR.
  • Human review tập trung vào Business Logic Correctness (Giá trị 5000 có đúng không?) chứ không phải Syntax/Style.

11.4. Kết Luận: “Tên Hằng” – Đâu Chỉ Là Tên Gọi

Năm 2026, trong môi trường DevOps, Cloud Native, Microservices, Polyglot, và Team đa quốc gia (Việt – Nhật – Anh – Ấn…), việc đặt tên hằng số (Constants Naming) là một dạng giao tiếp kỹ thuật (Technical Communication).

Một tên hằng tốt (ORDER_MAX_ITEMS_PER_CART)胜过 một comment xấu (// max items).
Một tên hằng có đơn vị (TIMEOUT_MS) ngăn chặn một sự cố production lúc 3 giờ sáng.
Một tên hằng tuân thủ Convention (SCREAMING_SNAKE_CASE vs PascalCase) thể hiện sự tôn trọng ngôn ngữ và cộng đồng.
Một hằng Master Data được model bằng Enum thay vì String magic number thể hiện tư duy Domain-Driven Design.

Checklist “Definition of Done” cho một Constant năm 2026:

  • Naming: Đúng Convention ngôn ngữ (SCREAMING_SNAKE / PascalCase).
  • Semantics: Tên mô tả đủ ý nghĩa (What), không cần comment giải thích (Why).
  • Unit: Có Suffix đơn vị (_MS, _YEN, _COUNT) HOẶC dùng Strong Type (Duration, Yen, ByteSize).
  • Immutability: Là final/const/readonly/static/const/let (immutable binding) + Immutable Object (nếu phức tạp).
  • Scope: private/internal/package-private tối đa. public/exported chỉ khi cần thiết (API Contract).
  • Location: Nằm đúng Package/Module/Domain (Không phải God Class).
  • Source: Hardcoded (Business Rule) vs Injected (Config/Secret) -> Phân biệt rõ ràng.
  • Doc: Có JavaDoc/Docstring/Rustdoc cho public constants (Ý nghĩa, Đơn vị, Nguồn, Lịch sử).
  • Test: Có Unit Test kiểm tra giá trị/naming convention / Contract Test (nếu là API).
  • Security: KHÔNG chứa Secret/Credential.

Hãy đối xử với Constants như những Công Dân Thứ Nhất (First-Class Citizens) trong codebase. Chúng nhỏ bé, nhưng chúng là nền tảng vững chắc cho sự ổn định, an toàn và khả năng mở rộng của hệ thống phần mềm hiện đại tại Nhật Bản và toàn cầu.

Bài viết được biên soạn dựa trên các tiêu chuẩn: Google Java Style, Microsoft C# Coding Conventions, PEP 8, Rust API Guidelines, Go Code Review Comments, Effective Java 3rd Ed, Clean Code, DDD, Twelve-Factor App, và thực tế vận hành hệ thống Enterprise tại Nhật Bản năm 2026.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *