Awesome-claude-code create-visitor
Generates Visitor pattern for PHP 8.4. Creates operations on object structures without modifying element classes, with visitor interface, concrete visitors, and visitable elements. Includes unit tests.
install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/create-visitor" ~/.claude/skills/dykyi-roman-awesome-claude-code-create-visitor && rm -rf "$T"
manifest:
skills/create-visitor/SKILL.mdsource content
Visitor Pattern Generator
Creates Visitor pattern infrastructure for operations on object structures without modifying classes.
When to Use
| Scenario | Example |
|---|---|
| Operations on object structure | Calculate price/tax on order items |
| Adding operations without modification | Export visitors (JSON, XML, CSV) |
| Different operations on same elements | Validation, transformation, rendering |
| Double dispatch needed | Type-specific behavior without instanceof |
Component Characteristics
Visitor Interface
- Declares visit methods for each element type
- One method per visitable element
- Returns operation result
- Enables double dispatch
Concrete Visitors
- Implement specific operations
- Process each element type differently
- Encapsulate algorithm logic
- Can accumulate state during traversal
Visitable Elements
- Accept visitor via accept() method
- Call visitor's visit method with self
- Enable operation without modification
- Maintain element structure
Generation Process
Step 1: Generate Visitor Interface
Path:
src/Domain/{BoundedContext}/Visitor/
— Visitor contract with visit methods{Name}VisitorInterface.php
Step 2: Generate Concrete Visitors
Path:
src/Domain/{BoundedContext}/Visitor/ or src/Application/{BoundedContext}/
— First operation implementation{Operation1}Visitor.php
— Second operation implementation{Operation2}Visitor.php
— Third operation implementation{Operation3}Visitor.php
Step 3: Generate Visitable Interface
Path:
src/Domain/{BoundedContext}/
— Element contract with accept() methodVisitableInterface.php
Step 4: Update Existing Elements
Path:
src/Domain/{BoundedContext}/
- Add
to element classesimplements VisitableInterface - Add
method to each elementaccept()
Step 5: Generate Tests
— Individual visitor tests{Operation}VisitorTest.php
— Element accept() tests{Element}AcceptTest.php
File Placement
| Component | Path |
|---|---|
| Visitor Interface | |
| Concrete Visitors (Domain) | |
| Concrete Visitors (Application) | |
| Visitable Interface | |
| Unit Tests | |
Naming Conventions
| Component | Pattern | Example |
|---|---|---|
| Visitor Interface | | |
| Concrete Visitor | | |
| Visitable Interface | | |
| Visit Method | | |
| Accept Method | | |
| Test | | |
Quick Template Reference
Visitor Interface
interface {Name}VisitorInterface { public function visit{Element1}({Element1} $element): {ReturnType}; public function visit{Element2}({Element2} $element): {ReturnType}; public function visit{Element3}({Element3} $element): {ReturnType}; }
Concrete Visitor
final class {Operation}Visitor implements {Name}VisitorInterface { public function visit{Element1}({Element1} $element): {ReturnType} { // Element1-specific operation } public function visit{Element2}({Element2} $element): {ReturnType} { // Element2-specific operation } }
Visitable Interface
interface VisitableInterface { public function accept({Name}VisitorInterface $visitor): mixed; }
Visitable Element
final readonly class {Element} implements VisitableInterface { public function accept({Name}VisitorInterface $visitor): mixed { return $visitor->visit{Element}($this); } }
Usage Example
// Create elements $order = new Order(items: [ new Product(price: 100, quantity: 2), new Service(price: 50, duration: 1), new Discount(amount: 20), ]); // Apply different visitors $priceVisitor = new PriceCalculatorVisitor(); $taxVisitor = new TaxCalculatorVisitor(rate: 0.2); $exportVisitor = new JsonExportVisitor(); $totalPrice = $order->accept($priceVisitor); $totalTax = $order->accept($taxVisitor); $json = $order->accept($exportVisitor);
Common Visitor Operations
| Domain | Visitors |
|---|---|
| Order Items | PriceCalculator, TaxCalculator, DiscountApplier |
| AST/Expression Tree | Evaluator, Formatter, Validator |
| Document Structure | Renderer, Counter, Searcher |
| File System | SizeCalculator, Permissions, Backup |
| Shopping Cart | TotalCalculator, ShippingCost, Export |
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|---|---|
| instanceof in visitor | Defeats purpose | Use proper visit methods |
| Mutable visitor state | Race conditions | Use readonly classes |
| Too many element types | Visitor interface bloat | Split into multiple visitors |
| Breaking element encapsulation | Tight coupling | Expose getters, not internals |
| Returning void | Limited usefulness | Return operation results |
References
For complete PHP templates and examples, see:
— Visitor Interface, Concrete Visitor, Visitable Element templatesreferences/templates.md
— PriceCalculator, TaxCalculator, Export visitors with testsreferences/examples.md