Skip to content
advanced Phase 109 · Technical Debt

Identifying Technical Debt in Magento 2

Techniques for identifying technical debt through code smells, architecture smells, and process smells in Magento 2 codebases

45m
2 problems
Topic Progress 0%

Code Smells in Magento 2

What Are Code Smells?

Code smells are surface-level indicators of deeper problems. They are not bugs but suggest structural issues.

Common Magento 2 Code Smells

God Classes

// BAD: Class with too many responsibilities
class CatalogProduct implements ProductInterface
{
    public function save() { /* 200 lines */ }
    public function validate() { /* 150 lines */ }
    public function load() { /* 100 lines */ }
    public function delete() { /* 80 lines */ }
    public function sendEmail() { /* 120 lines */ }
    public function generateSku() { /* 90 lines */ }
    // ... 30 more methods
}

Long Parameter Lists

// BAD: Constructor with too many dependencies
public function __construct(
    LoggerInterface $logger,
    Registry $registry,
    StoreManagerInterface $storeManager,
    ConfigInterface $config,
    CacheInterface $cache,
    ResourceManager $resourceManager,
    EntityManager $entityManager,
    EventManager $eventManager,
    ComposerInformation $composerInfo,
    ProductFactory $productFactory
) {}

Duplicated Code

// Found in multiple classes - copy-paste pattern
public function formatPrice($price)
{
    return number_format($price, 2, '.', '');
}

// Magento already has PriceCurrencyInterface for this

Dead Code

// Methods never called anywhere
class LegacyHelper
{
    public function oldMethod() { /* unused */ }
    public function deprecatedLogic() { /* no callers */ }
    private $obsoleteProperty; // never read
}

Feature Envy

// BAD: Method uses more of another class than its own
class OrderProcessor
{
    public function process(Order $order)
    {
        $order->getBillingAddress()->getCity();
        $order->getShippingAddress()->getCountryId();
        $order->getPayment()->getMethod();
        $order->getCustomer()->getEmail();
        // ... 20 more $order calls
    }
}

Architecture Smells

System-Level Debt Indicators

Circular Dependencies

// Module A depends on Module B
// Module B depends on Module A
// Result: cannot install/remove either independently

// Check with:
php bin/magento dev:module:graph

Over-Coupled Modules

<!-- Module directly depends on specific implementation -->
<type name="Magento\Catalog\Model\Product">
    <plugin name="inventory" type="Vendor\Inventory\Plugin\ProductPlugin"/>
</type>

<!-- Better: depend on interface -->
<type name="Magento\Catalog\Api\ProductInterface">
    <!-- abstracted dependency -->
</type>

Missing Abstractions

// BAD: Direct instantiation throughout codebase
$order = new \Magento\Sales\Model\Order();

// BETTER: Factory pattern (already in Magento)
$order = $this->orderFactory->create();

// WORST: Direct database calls bypassing models
$db->query('SELECT * FROM sales_order WHERE ...');

Technology Lock-In Symptoms

- Cannot upgrade Magento version due to module conflicts
- Custom code depends on deprecated APIs
- Third-party modules prevent core updates
- Manual processes required for deployments

Database Schema Smells

-- Missing indexes (slow queries)
SELECT * FROM catalog_product_entity WHERE sku = 'X';
-- catalog_product_entity_sku index exists but not used

-- Over-normalization
catalog_product_entity_int → catalog_product_entity_varchar → eav_attribute
-- 4 JOINs to get one attribute value

Configuration Sprawl

- Same setting duplicated across multiple XML files
- Environment-specific values hardcoded in config
- Inconsistent naming conventions across modules
- Deeply nested configuration inheritance

Process Smells

Development Process Debt

Missing Code Review

Symptoms:
- Code merged without review
- Inconsistent coding standards
- Security issues reaching production
- Knowledge concentrated in few developers

Inadequate Testing

// Test coverage gaps
class ProductTest extends TestCase
{
    public function testCreateProduct() {
        // Only tests happy path
        // Missing: edge cases, error handling, performance
    }
}

// No integration tests for critical flows
// Missing test data management
// Flaky tests ignored rather than fixed

Documentation Debt

- No README or outdated README
- Missing architecture decision records
- API endpoints undocumented
- Deployment process tribal knowledge
- Onboarding relies on shadowing

CI/CD Debt

# Missing or incomplete pipeline
stages:
  - build
  - deploy  # No testing stage!

# Manual deployment steps
# No rollback procedure
# No monitoring or alerting

Dependency Management Debt

// composer.json with pinned outdated versions
{
    "require": {
        "magento/framework": "103.0.5",
        "php": ">=7.4"
    }
}
// Should be >=8.1 for Magento 2.4.6+

Debt Metrics

# Measure with PHPStan/Psalm
vendor/bin/phpstan analyse --level=6 src/

# Count TODO/FIXME/HACK comments
rg -c 'TODO|FIXME|HACK|WORKAROUND' --include='*.php'

# Check code duplication
phpmd src/ text codesize,cleancode

Debt Detection Tools

Static Analysis Tools

PHPStan for Magento

# Install
composer require --dev phpstan/phpstan magento/magento-coding-standard

# Run
vendor/bin/phpstan analyse --level=6 app/code/Vendor/Module/

# phpstan.neon
parameters:
    level: 6
    paths:
        - app/code/Vendor
    ignoreErrors:
        - '#Call to an undefined method#'

Magento Coding Standard

# Install
composer require --dev magento/magento-coding-standard

# Run
vendor/bin/phpcs --standard=Magento2 app/code/Vendor/Module/

# Auto-fix
vendor/bin/phpcbf --standard=Magento2 app/code/Vendor/Module/

Technical Debt Indicators Dashboard

// Custom CLI command to measure debt
$ php bin/magento debt:report

Module                          | Complexity | Duplication | TODOs | Rating
Vendor_Catalog                  | 45         | 12%         | 3     | C
Vendor_Checkout                 | 78         | 23%         | 7     | D
Vendor_Inventory                | 32         | 5%          | 1     | A

Code Complexity Metrics

``n
Cyclomatic Complexity:

  • 1-10: Simple, low risk
  • 11-20: Moderate, review needed
  • 21-50: Complex, refactoring candidate
  • 50+: Unmaintainable, immediate action

Lines of Code:

  • Methods > 50 lines: likely doing too much
  • Classes > 500 lines: consider splitting
  • Files > 1000 lines: architectural review needed

### Debt Backlog Management
  1. Identify debt during code review
  2. Create ticket with debt type and impact
  3. Tag with affected module/area
  4. Estimate remediation effort
  5. Prioritize with feature work
  6. Track debt ratio over time

Practice Problems

0 / 2 solved
Identify Code Smells

Given a Magento module with 15 PHP files, identify at least 5 code smells and explain their impact.

Architecture Debt Audit

Audit a Magento installation for circular dependencies and over-coupling. Document findings.

Quiz

1. What is a 'code smell'?

Question 1 options

2. Which tool measures cyclomatic complexity in PHP?

Question 2 options

3. What indicates 'architecture smell' in Magento?

Question 3 options

4. A class with 30+ constructor dependencies suggests what problem?

Question 4 options

Flashcards

Question

What is a code smell?

Answer

A surface-level indicator suggesting deeper structural problems in code

Question

Name 3 common code smells in Magento

Answer

God classes, long parameter lists, duplicated code, feature envy, dead code

Question

What is architecture smell?

Answer

System-level issues like circular dependencies, over-coupling, and missing abstractions

Question

How to detect circular dependencies?

Answer

Run php bin/magento dev:module:graph to visualize module relationships

Question

What PHP tool measures code complexity?

Answer

PHPMD (PHP Mess Detector) measures cyclomatic complexity

Revision Notes

Key Takeaways

  • 1. Code smells are indicators, not bugs—address them before they become problems
  • 2. God classes, long parameters, and duplication are the most common Magento code smells
  • 3. Architecture smells include circular dependencies and over-coupling between modules
  • 4. Process smells include missing reviews, inadequate testing, and documentation gaps
  • 5. Use PHPStan, PHPMD, and Magento Coding Standard to measure debt quantitatively
  • 6. Track debt metrics over time and manage debt like any other backlog item

Interview Tips

  • Explain the difference between a bug and a code smell
  • Describe 3 code smells you have found in real Magento projects
  • How do you measure and track technical debt?
  • When is it acceptable to take on technical debt?
  • Describe a refactoring you performed to address technical debt

Cheat Sheet

Identifying Technical Debt Cheat Sheet

Code Smells: God class, long params, duplication, feature envy, dead code
Architecture Smells: Circular deps, over-coupling, missing abstractions, schema issues
Process Smells: No review, missing tests, no docs, manual deploys

Tools:

  • PHPStan: static analysis
  • PHPMD: complexity metrics
  • Magento Coding Standard: coding standards
  • dev:module:graph: dependency visualization

Metrics: Cyclomatic complexity, LOC, duplication %, TODO count