acc-create-state
1
总安装量
1
周安装量
#46637
全站排名
安装命令
npx skills add https://github.com/dykyi-roman/awesome-claude-code --skill acc-create-state
Agent 安装分布
opencode
1
claude-code
1
Skill 文档
State Pattern Generator
Creates State pattern infrastructure for objects that change behavior based on internal state.
When to Use
| Scenario | Example |
|---|---|
| Object behavior varies by state | Order (pending, paid, shipped) |
| Many conditionals based on state | Document workflow |
| State-specific transitions | Subscription lifecycle |
| Finite state machines | Payment processing |
Component Characteristics
StateInterface
- Defines available actions
- Returns new state after transition
- Encapsulates state-specific behavior
Context
- Holds current state
- Delegates actions to state
- Manages state transitions
Concrete States
- Implement behavior for each state
- Handle valid/invalid transitions
- Return appropriate next state
Generation Process
Step 1: Analyze State Machine
Determine:
- All possible states
- Actions/transitions between states
- Which actions are valid per state
- Terminal states (no outgoing transitions)
Step 2: Generate State Components
Path: src/Domain/{BoundedContext}/State/
{Name}StateInterface.phpâ State contract with all actionsAbstract{Name}State.phpâ Base class with default (invalid) implementations{StateName}State.phpâ Concrete state for each state (PendingState, PaidState, etc.){Name}StateFactory.phpâ Factory for reconstitution from storage
Path: src/Domain/{BoundedContext}/Exception/
InvalidStateTransitionException.phpâ Exception for invalid transitions
Step 3: Update Entity
Path: src/Domain/{BoundedContext}/Entity/
Update entity to use state pattern with delegation methods.
Step 4: Generate Tests
Path: tests/Unit/Domain/{BoundedContext}/State/
{StateName}StateTest.phpâ Test each concrete state{Entity}StateTransitionTest.phpâ Test full state machine
File Placement
| Component | Path |
|---|---|
| State Interface | src/Domain/{BoundedContext}/State/ |
| Concrete States | src/Domain/{BoundedContext}/State/ |
| State Factory | src/Domain/{BoundedContext}/State/ |
| Entity with State | src/Domain/{BoundedContext}/Entity/ |
| Exception | src/Domain/{BoundedContext}/Exception/ |
| Unit Tests | tests/Unit/Domain/{BoundedContext}/State/ |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Interface | {Name}StateInterface |
OrderStateInterface |
| Abstract State | Abstract{Name}State |
AbstractOrderState |
| Concrete State | {StateName}State |
PendingState, PaidState |
| Factory | {Name}StateFactory |
OrderStateFactory |
| Exception | InvalidStateTransitionException |
InvalidStateTransitionException |
| Test | {ClassName}Test |
PendingStateTest |
Quick Template Reference
State Interface
interface {Name}StateInterface
{
public function getName(): string;
public function {action1}({Context} $context): self;
public function {action2}({Context} $context): self;
public function canTransitionTo(self $state): bool;
/** @return array<string> */
public function allowedTransitions(): array;
}
Abstract State
abstract readonly class Abstract{Name}State implements {Name}StateInterface
{
public function {action1}({Context} $context): {Name}StateInterface
{
throw InvalidStateTransitionException::actionNotAllowed('{action1}', $this->getName());
}
public function canTransitionTo({Name}StateInterface $state): bool
{
return in_array($state->getName(), $this->allowedTransitions(), true);
}
}
Concrete State
final readonly class {StateName}State extends Abstract{Name}State
{
public function getName(): string
{
return '{state_name}';
}
public function {action1}({Context} $context): {Name}StateInterface
{
$context->recordEvent(new {Event}($context->id()));
return new {NextState}State();
}
public function allowedTransitions(): array
{
return ['{next_state_1}', '{next_state_2}'];
}
}
State Factory
final class {Name}StateFactory
{
public static function fromName(string $name): {Name}StateInterface
{
return match ($name) {
'pending' => new PendingState(),
'confirmed' => new ConfirmedState(),
default => throw new \InvalidArgumentException("Unknown state: $name"),
};
}
}
Usage Example
// Entity with state
$order = new Order($id, $customerId, $items);
$order->confirm(); // Pending -> Confirmed
$order->pay(); // Confirmed -> Paid
$order->ship(); // Paid -> Shipped
$order->deliver(); // Shipped -> Delivered
// Check state
if ($order->isInState('delivered')) {
// ...
}
// Reconstitute from storage
$state = OrderStateFactory::fromName($row['state']);
$order = new Order($id, $customerId, $items, $state);
State Diagram Template
ââââââââââââ action1 ââââââââââââ action2 ââââââââââââ
â State1 âââââââââââââ¶â State2 âââââââââââââ¶â State3 â
ââââââ¬ââââââ ââââââ¬ââââââ ââââââââââââ
â â
â cancel â cancel
â â
â¼ â¼
ââââââââââââ ââââââââââââ
âCancelled â âCancelled â
ââââââââââââ ââââââââââââ
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| Mutable States | Shared state pollution | Make states readonly |
| God State | One state handles all | Split into specific states |
| Missing Transitions | Silent failures | Throw on invalid action |
| State in Entity | Mixed concerns | Extract to State classes |
| No Factory | Hard to reconstitute | Add StateFactory |
References
For complete PHP templates and examples, see:
references/templates.mdâ State interface, abstract, concrete templatesreferences/examples.mdâ Order state machine example and tests