refactoring
Refactoring
A thorough reference covering 89 refactoring techniques and code smells — featuring PHP 8.3+ examples, rationale, step-by-step mechanics, and before/after comparisons.
Refactoring Techniques (67)
Composing Methods
- Extract Method — Pull code fragments into named methods → reference
- Inline Method — Substitute a method call with its body → reference
- Extract Variable — Give complex expressions meaningful names through explanatory variables → reference
- Inline Temp — Substitute a temporary variable with its expression → reference
- Replace Temp with Query — Swap temp variables for method calls → reference
- Split Temporary Variable — Assign separate variables for separate purposes → reference
- Remove Assignments to Parameters — Introduce local variables rather than reassigning parameters → reference
- Replace Method with Method Object — Convert a complex method into its own class → reference
- Substitute Algorithm — Swap an algorithm for a clearer alternative → reference
Moving Features Between Objects
- Move Method — Relocate a method to the class that depends on it most → reference
- Move Field — Relocate a field to the class that depends on it most → reference
- Extract Class — Divide a class that handles too much → reference
- Inline Class — Consolidate a class that does too little → reference
- Hide Delegate — Introduce methods that conceal delegation chains → reference
- Remove Middle Man — Allow clients to call the delegate directly → reference
- Introduce Foreign Method — Attach a missing method to a class you cannot modify → reference
- Introduce Local Extension — Build a wrapper or subclass for a library class → reference
Organizing Data
- Self Encapsulate Field — Route field access through getters even within the class → reference
- Replace Data Value with Object — Promote primitive data to a rich object → reference
- Change Value to Reference — Convert value objects into reference objects → reference
- Change Reference to Value — Convert reference objects into value objects → reference
- Replace Array with Object — Swap arrays used as data structures for proper objects → reference
- Duplicate Observed Data — Keep domain data in sync with the UI via Observer → reference
- Change Unidirectional to Bidirectional — Introduce back-references when needed → reference
- Change Bidirectional to Unidirectional — Eliminate unnecessary back-references → reference
- Replace Magic Number with Symbolic Constant — Assign meaningful names to magic numbers → reference
- Encapsulate Field — Restrict field visibility, expose accessors → reference
- Encapsulate Collection — Expose read-only views of collections → reference
- Replace Type Code with Class — Swap type codes for enums or classes → reference
- Replace Type Code with Subclasses — Swap type codes for a class hierarchy → reference
- Replace Type Code with State/Strategy — Swap behavior-affecting type codes for State/Strategy → reference
- Replace Subclass with Fields — Eliminate subclasses that differ only in constants → reference
Simplifying Conditional Expressions
- Decompose Conditional — Break complex conditionals into named methods → reference
- Consolidate Conditional Expression — Merge conditions that produce the same result → reference
- Consolidate Duplicate Conditional Fragments — Hoist identical code outside of conditionals → reference
- Remove Control Flag — Swap control flags for break/return/continue → reference
- Replace Nested Conditional with Guard Clauses — Flatten nested conditionals using early returns → reference
- Replace Conditional with Polymorphism — Swap conditionals for polymorphic method calls → reference
- Introduce Null Object — Swap null checks for a null object → reference
- Introduce Assertion — Insert assertions to document assumptions → reference
Simplifying Method Calls
- Rename Method — Choose method names that reveal their purpose → reference
- Add Parameter — Introduce new parameters to support additional data → reference
- Remove Parameter — Drop unused method parameters → reference
- Separate Query from Modifier — Divide methods that both return values and change state → reference
- Parameterize Method — Unify similar methods by adding a parameter → reference
- Replace Parameter with Explicit Methods — Produce separate methods for each parameter value → reference
- Preserve Whole Object — Pass the entire object rather than individual values → reference
- Replace Parameter with Method Call — Derive values internally instead of passing them in → reference
- Introduce Parameter Object — Bundle related parameters into an object → reference
- Remove Setting Method — Eliminate setters for fields assigned only at creation → reference
- Hide Method — Narrow the visibility of unused public methods → reference
- Replace Constructor with Factory Method — Use factory methods for complex object creation → reference
- Replace Error Code with Exception — Throw exceptions rather than returning error codes → reference
- Replace Exception with Test — Validate conditions upfront instead of catching exceptions → reference
Dealing with Generalization
- Pull Up Field — Promote identical fields to the superclass → reference
- Pull Up Method — Promote identical methods to the superclass → reference
- Pull Up Constructor Body — Promote shared constructor logic to the superclass → reference
- Push Down Method — Relocate a method to the subclass that uses it → reference
- Push Down Field — Relocate a field to the subclass that uses it → reference
- Extract Subclass — Carve out a subclass for a subset of features → reference
- Extract Superclass — Hoist shared behavior into a parent class → reference
- Extract Interface — Define a shared interface for common operations → reference
- Collapse Hierarchy — Merge superclass and subclass when they are too similar → reference
- Form Template Method — Generalize similar methods into a template → reference
- Replace Inheritance with Delegation — Swap inheritance for composition → reference
- Replace Delegation with Inheritance — Swap excessive delegation for inheritance → reference
Code Smells (22)
Bloaters
- Long Method — Methods that have grown excessively long → reference
- Large Class — Classes that try to handle too much → reference
- Primitive Obsession — Excessive use of primitives instead of small objects → reference
- Long Parameter List — Methods accepting too many parameters → reference
- Data Clumps — Groups of data that repeatedly appear together → reference
Object-Orientation Abusers
- Alternative Classes with Different Interfaces — Similar classes with mismatched method signatures → reference
- Refused Bequest — Subclasses that disregard inherited behavior → reference
- Switch Statements — Complex switch/match constructs that should be polymorphism → reference
- Temporary Field — Fields populated only under certain conditions → reference
Change Preventers
- Divergent Change — A single class modified for many unrelated reasons → reference
- Parallel Inheritance Hierarchies — Creating one subclass forces creating another → reference
- Shotgun Surgery — A single change demands edits across many classes → reference
Dispensables
- Comments — Excessive comments that mask unclear code → reference
- Duplicate Code — Identical or nearly identical code in multiple locations → reference
- Data Class — Classes consisting of nothing but fields and getters/setters → reference
- Dead Code — Unreachable or unused code → reference
- Lazy Class — Classes that contribute too little to justify their existence → reference
- Speculative Generality — Unused abstractions built "just in case" → reference
Couplers
- Feature Envy — Methods that rely more on another class's data than their own → reference
- Inappropriate Intimacy — Classes that reach into each other's internals → reference
- Incomplete Library Class — Library classes that fall short of providing needed features → reference
- Message Chains — Long chains of method calls (a.b().c().d()) → reference
- Middle Man — Classes that do nothing but delegate to another class → reference
Best Practices
- Refactor in small, verified steps — execute tests after every change
- Follow the Boy Scout Rule: leave code in better shape than you found it
- Reach for IDE refactoring tools when available for safe, automated transformations
- Never refactor and alter behavior simultaneously — keep them separate
- Prioritize refactoring that lowers coupling and raises cohesion
- Tackle code smells nearest to your current work first
More from krzysztofsurdy/code-virtuoso
symfony-upgrade
Symfony framework version upgrade guide using the deprecation-first approach. Use when the user asks to upgrade Symfony to a new minor or major version, fix deprecation warnings, update Symfony recipes, check bundle compatibility, migrate between LTS versions, or plan a Symfony version migration strategy. Covers PHPUnit Bridge deprecation tracking, recipe updates, bundle compatibility checks, version-specific breaking changes, and the changelog-first upgrade workflow.
87symfony-components
Comprehensive reference for all 38 Symfony framework components with PHP 8.3+ and Symfony 7.x patterns. Use when the user asks to implement, configure, or troubleshoot any Symfony component including HttpFoundation, HttpKernel, DependencyInjection, Form, Validator, Cache, Messenger, Console, EventDispatcher, Workflow, Serializer, Security, Routing, Twig, Doctrine integration, or any other Symfony component. Covers APIs, configuration, best practices, and common pitfalls.
80solid
SOLID principles for object-oriented design with multi-language examples (PHP, Java, Python, TypeScript, C++). Use when the user asks to review SOLID compliance, fix a SOLID violation, evaluate class design, reduce coupling, improve extensibility, or apply Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, or Dependency Inversion principles. Covers motivation, violation detection, refactoring fixes, and real-world trade-offs for each principle.
46agentic-rules-writer
Interactive tool to generate tailored rules and instruction files for any AI coding agent. Use when the user asks to set up agent rules, configure Claude Code instructions, create Cursor rules, write Windsurf rules, generate Copilot instructions, or establish consistent AI coding standards for a team. Supports 13+ agents (Claude Code, Cursor, Windsurf, Copilot, Gemini, Codex, Cline, OpenCode, Continue, Trae, Roo Code, Amp) with global, team-shared, and dev-specific scopes. Defers to the `using-ecosystem` meta-skill for ecosystem discovery (skills, agents, recommendations) and runs an interactive questionnaire for workflow preferences.
46clean-architecture
Clean Architecture, Hexagonal Architecture (Ports and Adapters), and Domain-Driven Design fundamentals. Use when the user asks to design system architecture, define layer boundaries, apply DDD tactical patterns (entities, value objects, aggregates, repositories), structure a hexagonal application, enforce dependency rules, or evaluate whether a codebase needs architectural refactoring. Covers bounded contexts, use cases, domain services, and framework-independent design.
40security
Application security principles and OWASP Top 10 for building secure web applications. Use when the user asks to review code for security vulnerabilities, implement authentication or authorization, handle secrets or API keys, configure security headers, prevent injection attacks (SQL, XSS, CSRF), prepare for a security audit, or respond to a vulnerability report. Covers input validation, data protection, secrets management, session handling, and common security antipatterns.
39