代碼實作階段觸發。強制執行統一的編碼規範,支援 Java、TypeScript、Go 多語言。包含 Input/Output 模式、依賴注入、不可變物件等規範,確保代碼風格一致性。
Enforces unified coding standards across Java, TypeScript, and Go during code implementation. Triggers when writing new code, reviewing code, or generating Use Cases to ensure consistent style and architecture.
/plugin marketplace add knowlet/skills/plugin install knowlet-skills@knowlet/skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/GOLANG.mdreferences/JAVA_CLEAN_ARCH.mdreferences/RUST.mdreferences/TYPESCRIPT.md強制執行統一的編碼規範,確保 AI 生成的代碼風格高度一致,降低人類審閱成本。
根據專案語言選擇對應的規範:
| 語言 | 參考文件 | 說明 |
|---|---|---|
| Java | 本文件 | Spring Boot / Jakarta EE |
| Java | references/JAVA_CLEAN_ARCH.md | Clean Architecture 詳細結構 |
| TypeScript | references/TYPESCRIPT.md | Node.js / Deno / Bun |
| Go | references/GOLANG.md | Standard Go Project Layout |
| Rust | references/RUST.md | Cargo / Tokio async runtime |
當被其他 Sub-agent 呼叫時,本 Skill 提供語言特定的編碼規範:
command-sub-agent 呼叫 → 提供 Use Case / Command Handler 的編碼規範
query-sub-agent 呼叫 → 提供 Query Handler / Read Model 的編碼規範
reactor-sub-agent 呼叫 → 提供 Event Handler 的編碼規範
public class CreateOrderUseCase {
// ✅ Input 定義為靜態內部類別
public static class Input {
private final CustomerId customerId;
private final List<OrderItemRequest> items;
private final ShippingAddress address;
public Input(CustomerId customerId,
List<OrderItemRequest> items,
ShippingAddress address) {
// 可在此進行基本驗證
Objects.requireNonNull(customerId, "customerId must not be null");
Objects.requireNonNull(items, "items must not be null");
if (items.isEmpty()) {
throw new IllegalArgumentException("items must not be empty");
}
this.customerId = customerId;
this.items = List.copyOf(items);
this.address = address;
}
// Getters
public CustomerId getCustomerId() { return customerId; }
public List<OrderItemRequest> getItems() { return items; }
public ShippingAddress getAddress() { return address; }
}
// ✅ Output 定義為靜態內部類別
public static class Output {
private final OrderId orderId;
private final OrderStatus status;
private final LocalDateTime createdAt;
public Output(OrderId orderId, OrderStatus status, LocalDateTime createdAt) {
this.orderId = orderId;
this.status = status;
this.createdAt = createdAt;
}
// Getters
public OrderId getOrderId() { return orderId; }
public OrderStatus getStatus() { return status; }
public LocalDateTime getCreatedAt() { return createdAt; }
}
// ✅ 主要執行方法,接收 Input,回傳 Output
public Output execute(Input input) {
// 業務邏輯
}
}
// ❌ 禁止:直接使用多個參數
public OrderResult createOrder(String customerId, List<Item> items, String address) {
// 這樣做會讓介面難以維護
}
// ❌ 禁止:使用 Map 作為輸入輸出
public Map<String, Object> createOrder(Map<String, Object> params) {
// 這樣做會失去型別安全
}
// ✅ 正確:使用 @Configuration + @Bean
@Configuration
public class UseCaseConfiguration {
@Bean
public CreateOrderUseCase createOrderUseCase(
OrderRepository orderRepository,
InventoryService inventoryService,
EventPublisher eventPublisher) {
return new CreateOrderUseCase(
orderRepository,
inventoryService,
eventPublisher
);
}
@Bean
public CancelOrderUseCase cancelOrderUseCase(
OrderRepository orderRepository,
PaymentGateway paymentGateway) {
return new CancelOrderUseCase(orderRepository, paymentGateway);
}
}
// ✅ Use Case 類別保持純淨,無 Spring 註解
public class CreateOrderUseCase {
private final OrderRepository orderRepository;
private final InventoryService inventoryService;
private final EventPublisher eventPublisher;
// 建構子注入
public CreateOrderUseCase(
OrderRepository orderRepository,
InventoryService inventoryService,
EventPublisher eventPublisher) {
this.orderRepository = orderRepository;
this.inventoryService = inventoryService;
this.eventPublisher = eventPublisher;
}
}
// ❌ 禁止:在 Use Case 上使用 @Component/@Service
@Service // ❌ 不要這樣做
public class CreateOrderUseCase {
@Autowired // ❌ 不要這樣做
private OrderRepository orderRepository;
}
以下情況可使用 @Component 系列註解:
| 類型 | 允許使用 | 說明 |
|---|---|---|
| Controller | @RestController | 展示層入口點 |
| Repository 實作 | @Repository | Infrastructure 層 |
| Event Listener | @Component | 技術性元件 |
| Scheduled Task | @Component | 技術性元件 |
// ✅ 動詞 + 名詞 + UseCase
CreateOrderUseCase
CancelOrderUseCase
UpdateCustomerProfileUseCase
// ✅ CQRS Command Handler
CreateOrderCommandHandler
CancelOrderCommandHandler
// ✅ CQRS Query Handler
GetOrderByIdQueryHandler
ListOrdersByCustomerQueryHandler
// ✅ Use Case 統一使用 execute()
public Output execute(Input input)
// ✅ Command Handler 統一使用 handle()
public void handle(CreateOrderCommand command)
// ✅ Query Handler 統一使用 handle()
public OrderDto handle(GetOrderByIdQuery query)
public static class Input {
private final CustomerId customerId; // ✅ final
private final List<OrderItemRequest> items;
public Input(CustomerId customerId, List<OrderItemRequest> items) {
this.customerId = customerId;
this.items = List.copyOf(items); // ✅ 防禦性複製
}
// ✅ 只有 Getter,沒有 Setter
public CustomerId getCustomerId() { return customerId; }
public List<OrderItemRequest> getItems() {
return items; // 已經是不可變的
}
}
// ✅ 定義領域特定例外
public class OrderNotFoundException extends DomainException {
public OrderNotFoundException(OrderId orderId) {
super("Order not found: " + orderId.getValue());
}
}
public class InsufficientInventoryException extends DomainException {
public InsufficientInventoryException(ProductId productId, int requested, int available) {
super(String.format(
"Insufficient inventory for product %s: requested %d, available %d",
productId.getValue(), requested, available
));
}
}
rules:
- id: no-component-on-usecase
pattern: "@(Component|Service).*class.*UseCase"
message: "Use @Bean configuration instead of @Component on UseCase classes"
severity: error
- id: no-autowired-field
pattern: "@Autowired\\s+private"
message: "Use constructor injection instead of field injection"
severity: error
- id: require-input-output-class
pattern: "class.*UseCase.*execute\\((?!Input)"
message: "UseCase.execute() should accept Input inner class"
severity: warning
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.