This skill encodes universal engineering standards for object-oriented software. When applied, Claude enforces these rules across any OOP language — the principles are language-agnostic unless a specific rule maps naturally to the target language's idioms.
The user may ask for code review, generation, refactoring, architecture design, test writing, or database schema design. Apply whichever sections are relevant.
No leading/trailing underscores or special symbols in public identifiers. Names like _name, name_, $obj are forbidden.
No mixing of local language phonetics with a foreign language in the same identifier. Use either full English or full native language — never a hybrid like getUserPingfen().
Class names: Use UpperCamelCase. Exception: well-known domain abbreviations (e.g. DTO, VO, BO) may retain their canonical form.
UserAccount, OrderService, XmlParseruserAccount, XMLparser, order_serviceMethods, parameters, local variables: Use lowerCamelCase.
getUserById, localValue, inputUserIdConstants: All uppercase with underscore separators. Prefer full descriptive names.
MAX_RETRY_COUNT, DEFAULT_TIMEOUT_SECONDSMAX, TIMEOUTAbstract classes: Prefix with Abstract or Base.
Exception classes: Suffix with Exception (e.g. PaymentException).
Test classes: Named after the class under test, suffixed with Test (e.g. OrderServiceTest).
Boolean fields in data objects: Do NOT prefix with is. Many serialization frameworks will misread isDeleted as field deleted, causing runtime failures.
deleted, active, enabledisDeleted, isActivePackages/modules: All lowercase, single semantic word per segment, singular form.
No opaque abbreviations: condi for condition, abs for abstract — forbidden. Names must be self-explanatory.
OrderFactory, LoginProxy, ResourceObserver.Translatable, Serializable, Configurable).Impl to distinguish from the interface (e.g. UserServiceImpl implements UserService).Enum; members are all-uppercase with underscores (e.g. OrderStatusEnum.PENDING_PAYMENT).LayerMethod prefix conventionDAO/Repositoryget (single), list (multiple), count, save/ insert, remove/ delete, updateDomain modelsXxxDO (data object), XxxDTO (transfer), XxxVO (view), XxxBO (business)
No magic values — never embed unexplained literals directly in logic.
cache.put("Id#order_" + orderId, value)ORDER_CACHE_KEY_PREFIX = "Id#order_" as a named constantLong/integer literals: Use uppercase suffix where the language requires it (e.g. 2L not 2l; 2.0f not 2.0F ambiguously).
Split constants by concern — do not create one monolithic Constants class. Group into CacheConstants, SecurityConstants, ConfigConstants, etc.
Constant scoping levels (from broadest to narrowest): cross-application shared → application-wide → module-level → package-level → class-private.
Use enums for named value sets — especially when values carry semantic meaning beyond their raw type (e.g. days of week, order statuses).
Brace style: Opening brace on the same line as the statement; closing brace on its own line. Empty bodies may be written as {} inline.
Indentation: 4 spaces. Never use tabs (or configure tabs as 4 spaces if the language convention mandates them).
Spaces around operators: All binary and ternary operators must have one space on each side ( =, &&, +, etc.).
No space between a function/method name and its opening parenthesis. No space after ( or before ).
Reserved words ( if, for, while, switch) require a space before the opening parenthesis.
Line length limit: 120 characters. When wrapping:
Comment spacing: One space between the comment marker and content ( // comment, # comment).
File encoding: UTF-8. Line endings: Unix ( LF).
Blank lines: One blank line between logically distinct blocks within a method. No need for multiple blank lines as separators.
Access statics via class name, not via an instance reference.
Always annotate overridden methods (e.g. @Override in Java/Kotlin, explicit override keyword in others). This surfaces signature mismatches at compile time.
Wrapper/boxed types for data object fields — primitive defaults can mask missing data (a 0 looks like valid data; null clearly signals "not set"). Use primitives only for local variables where performance matters.
Data objects (DTOs, POJOs, etc.): Do not assign default values to fields at declaration. Defaults hide missing assignments and cause subtle bugs.
No business logic in constructors. Use an explicit init() or factory method.
All data objects must implement a human-readable string representation ( __repr__, toString, etc.) for easier debugging.
Restrict access as tightly as possible:
StringBuilder, list join, etc.) — never += string in a loop body.final/ const/ val liberally: for classes not meant to be subclassed, for fields that must not be reassigned, for local variables that should not change.Arrays.asList() or equivalent — they are fixed-size adapters.iterator.remove().1 or -1 (never 0) violate contract and cause sort instability.capacity = (expected_count / load_factor) + 1.volatile (or equivalent) to prevent CPU/compiler reordering.switch statements: every case must either break/ return or have an explicit fall-through comment. Always include a default branch, placed last.
Always use braces for if/ else/ for/ while/ do — even single-line bodies.
Minimize if-else nesting — prefer early return / guard clauses over deeply nested branches. Max 3 levels of nesting; beyond that, refactor with guard clauses, strategy pattern, or state pattern.
Extract complex conditions into a well-named boolean variable before the if. Inline complex boolean expressions hurt readability.
Move invariants out of loops: object creation, DB connection acquisition, and avoidable try-catch blocks should live outside loop bodies.
Validate batch API inputs — enforce upper bounds on input sizes to prevent memory exhaustion.
Parameter validation rules:
Class-level, field-level, and method-level documentation must use the language's structured doc format (docstring, Javadoc, JSDoc, etc.) — not inline // comments.
All abstract methods / interface methods require doc comments explaining purpose, parameters, return values, exceptions, and any implementation constraints.
Every class must record its author and creation date.
Inline comments go on the line above the code they describe, not at the end of the line.
All enum members must have comments explaining their purpose.
Prefer clear native language comments over broken English — domain terms and keywords stay in English; explanations can be in the team's working language.
Keep comments in sync with code — stale comments are worse than no comments.
Do not comment out dead code silently — either delete it (version control preserves history) or leave a clear explanation above it with TODO/ FIXME markers.
Annotation markers:
TODO(author, date) — functionality not yet implemented.FIXME(author, date) — known broken code needing urgent fix.Comment quality target: comments should convey why and business meaning, not restate what the code does. Self-explanatory code needs no comment.
Prevent exceptions via pre-checks where possible — do not use exceptions as flow control.
Catch narrow exception types — avoid blanket catch(Exception) except at application boundaries.
Never swallow exceptions silently — either handle them or re-throw. An empty catch block is always wrong.
Transaction rollback: if an exception occurs inside a transaction, explicitly trigger rollback — don't rely on implicit behavior.
Always close resources in finally blocks (or use language-level resource management: with, try-with-resources, using, RAII, etc.).
Never return from a finally block — it silently swallows exceptions from the try block.
Caught exception type must match or be a parent of the thrown exception type.
NPE / null-safety discipline:
Error propagation strategy:
isSuccess(), error code, and error message.DRY principle: extract repeated validation or error-handling logic into shared private methods or base classes.
Use an abstraction layer (logging facade/interface) — do not bind directly to a specific logging library. This makes the implementation swappable.
Log retention: keep at least 15 days of logs (weekly-pattern anomalies require this window).
Log file naming convention: {appName}_{logType}_{description}.log — e.g. orderservice_monitor_paymentTimeout.log.
Guard log statements at debug/ trace level to avoid string interpolation cost when the level is inactive:
text
if logger.is_debug_enabled():
logger.debug(f"Processing order {order_id}")
Or use lazy interpolation syntax provided by the logging framework.
Prevent duplicate log propagation — configure appenders to avoid the same log entry appearing multiple times.
Exception log entries must include: context parameters AND the full stack trace.
Production log level discipline: no debug in production; info selectively; warn for recoverable anomalies; error for genuine system faults only.
print/console assertions — use framework assertions only.src/test/, tests/), never in the production source tree.Additional recommendations:
is_xxx, type unsigned tiny integer (0/1). All non-negative numeric fields must be unsigned.level_3_name is bad; level3_name is acceptable).user, order_item — not users).pk_ prefix for primary keys; uk_ for unique indexes; idx_ for regular indexes.DECIMAL/ NUMERIC — never FLOAT/ DOUBLE for stored values that require exact comparison.id (unsigned bigint, auto-increment primary key), gmt_create (datetime), gmt_modified (datetime).{business_domain}_{entity_role} (e.g. payment_task, trade_config).LIKE '%value%' defeats the index). Route full-text search to a search engine.SELECT * — always name columns explicitly.COUNT(*) is the standard row count; COUNT(col) skips NULLs. Use accordingly.IS NULL / IS NOT NULL or the equivalent function — direct equality comparison with NULL always yields NULL, not true/false.IN lists: keep under 1000 elements.gmt_modified when writing a record.Recommended layer hierarchy (each layer depends only on layers below it):
text
[ Open API / Gateway Layer ] [ Frontend / Template Layer ]
↓
[ Web / Controller Layer ]
↓
[ Service Layer ]
↓
[ Manager Layer ]
↓
[ DAO / Repository Layer ]
↓
[ Data Source / External APIs ]
Layer responsibilities:
Exception handling by layer:
Domain model types:
TypeMeaningDO / EntityMaps 1:1 to a DB table rowDTOData transferred between service boundariesBOEncapsulates business logic outputVOData shaped for the view/UI layerQuery objectEncapsulates query parameters (2+ params → object, not map)
MAJOR.MINOR.PATCH — start at 1.0.0. Major = breaking change; Minor = backward-compatible features; Patch = bug fixes.groupId + artifactId with different versions within the same build graph.