debtmap 0.16.7

Code complexity and technical debt analyzer
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
# Design Pattern Detection

Debtmap automatically detects common design patterns in your codebase to provide better architectural insights and reduce false positives in complexity analysis. When recognized design patterns are detected, Debtmap applies appropriate complexity adjustments to avoid penalizing idiomatic code.

## Overview

Debtmap detects 7 user-facing design patterns across Python, JavaScript, TypeScript, and Rust, plus 2 internal-only patterns (Builder, Visitor) used for scoring adjustments:

| Pattern | Primary Language | Detection Confidence | Type |
|---------|-----------------|---------------------|------|
| Observer | Python, Rust | High (0.8-0.9) | User-facing |
| Singleton | Python | High (0.85-0.95) | User-facing |
| Factory | Python | Medium-High (0.7-0.85) | User-facing |
| Strategy | Python | Medium (0.7-0.8) | User-facing |
| Callback | Python, JavaScript | High (0.8-0.9) | User-facing |
| Template Method | Python | Medium (0.7-0.8) | User-facing |
| Dependency Injection | Python | Medium (0.65-0.75) | User-facing |
| Builder | Rust | Internal | [Internal Only]#internal-pattern-detection |
| Visitor | Rust | Internal | [Internal Only]#internal-pattern-detection |

Pattern detection serves multiple purposes:
- **Reduces false positives**: Avoids flagging idiomatic pattern implementations as overly complex
- **Documents architecture**: Automatically identifies architectural patterns in your codebase
- **Validates consistency**: Helps ensure patterns are used correctly and completely
- **Guides refactoring**: Identifies incomplete pattern implementations

## Pattern Detection Details

### Observer Pattern

The Observer pattern is detected in Python and Rust by identifying abstract base classes with concrete implementations.

**Detection Criteria (Python)**:
- Abstract base class with `ABC`, `Protocol`, or `Interface` markers
- Abstract methods decorated with `@abstractmethod`
- Concrete implementations inheriting from the interface
- Methods prefixed with `on_`, `handle_`, or `notify_`
- Registration methods like `add_observer`, `register`, or `subscribe`
- Notification methods like `notify`, `notify_all`, `trigger`, `emit`

**Detection Criteria (Rust)**:
- Trait definitions with callback-style methods
- Multiple implementations of the same trait
- Trait registry tracking for cross-module detection

**Example (Python)**:
```python
from abc import ABC, abstractmethod

class EventObserver(ABC):
    @abstractmethod
    def on_event(self, data):
        """Handle event notification"""
        pass

class LoggingObserver(EventObserver):
    def on_event(self, data):
        print(f"Event occurred: {data}")

class EmailObserver(EventObserver):
    def on_event(self, data):
        send_email(f"Alert: {data}")

class EventManager:
    def __init__(self):
        self.observers = []

    def add_observer(self, observer: EventObserver):
        self.observers.append(observer)

    def notify_all(self, data):
        for observer in self.observers:
            observer.on_event(data)
```

**Confidence**: High (0.8-0.9) when abstract base class, implementations, and registration/notification methods are present. Lower confidence (0.5-0.7) for partial implementations.

### Singleton Pattern

Singleton pattern detection identifies three common Python implementations: module-level singletons, `__new__` override, and decorator-based patterns.

**Detection Criteria**:
- Module-level variable assignments (e.g., `instance = MyClass()`)
- Classes overriding `__new__` to enforce single instance
- Classes decorated with `@singleton` or similar decorators
- Presence of instance caching logic

**Example (Module-level)**:
```python
# config.py
class Config:
    def __init__(self):
        self.settings = {}

    def load(self, path):
        # Load configuration
        pass

# Single instance created at module level
config = Config()
```

**Example (`__new__` override)**:
```python
class DatabaseConnection:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.initialized = True
            self.connect()
```

**Example (Decorator-based)**:
```python
def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Logger:
    def __init__(self):
        self.log_file = open('app.log', 'a')
```

**Confidence**: Very High (0.9-0.95) for `__new__` override and decorator patterns. High (0.85) for module-level singletons with clear naming.

### Factory Pattern

Factory pattern detection identifies factory functions, factory classes, and factory registries based on naming conventions and structural patterns.

**Detection Criteria**:
- Functions with names containing `create_`, `make_`, `build_`, or `_factory`
- Factory registry patterns (dictionaries mapping types to constructors)
- Functions that return instances of different types based on parameters
- Classes with factory methods

**Example (Factory Function)**:
```python
def create_logger(log_type: str):
    if log_type == "file":
        return FileLogger()
    elif log_type == "console":
        return ConsoleLogger()
    elif log_type == "network":
        return NetworkLogger()
    else:
        raise ValueError(f"Unknown logger type: {log_type}")
```

**Example (Registry-based Factory)**:
```python
# Parser registry
PARSERS = {
    'json': JSONParser,
    'xml': XMLParser,
    'yaml': YAMLParser,
}

def create_parser(format: str):
    parser_class = PARSERS.get(format)
    if parser_class is None:
        raise ValueError(f"No parser for format: {format}")
    return parser_class()
```

**Example (Factory Method)**:
```python
class DocumentFactory:
    @staticmethod
    def create_document(doc_type: str):
        if doc_type == "pdf":
            return PDFDocument()
        elif doc_type == "word":
            return WordDocument()
        else:
            return PlainTextDocument()
```

**Confidence**: Medium-High (0.75-0.85) for functions with factory naming patterns. Lower confidence (0.6-0.7) for registry patterns without factory names.

### Strategy Pattern

Strategy pattern detection identifies interfaces with multiple implementations representing interchangeable algorithms.

**Detection Criteria**:
- Abstract base class or Protocol defining strategy interface
- Multiple concrete implementations
- Strategy interface typically has 1-2 core methods
- Used via composition (strategy object passed to context)

**Example**:
```python
from abc import ABC, abstractmethod

class CompressionStrategy(ABC):
    @abstractmethod
    def compress(self, data: bytes) -> bytes:
        pass

class ZipCompression(CompressionStrategy):
    def compress(self, data: bytes) -> bytes:
        return zlib.compress(data)

class GzipCompression(CompressionStrategy):
    def compress(self, data: bytes) -> bytes:
        return gzip.compress(data)

class LzmaCompression(CompressionStrategy):
    def compress(self, data: bytes) -> bytes:
        return lzma.compress(data)

class FileCompressor:
    def __init__(self, strategy: CompressionStrategy):
        self.strategy = strategy

    def compress_file(self, path):
        data = read_file(path)
        return self.strategy.compress(data)
```

**Confidence**: Medium (0.7-0.8) based on interface structure and implementation count.

### Callback Pattern

Callback pattern detection identifies decorator-based callbacks commonly used in web frameworks and event handlers.

**Detection Criteria**:
- Decorators with patterns like `@route`, `@handler`, `@app.`, `@on`, `@callback`
- Framework-specific decorators (Flask routes, FastAPI endpoints, event handlers)
- Functions registered as callbacks for events or hooks

**Example (Flask Routes)**:
```python
from flask import Flask

app = Flask(__name__)

@app.route('/api/users')
def get_users():
    return {"users": []}

@app.route('/api/users/<id>')
def get_user(id):
    return {"user": find_user(id)}
```

**Example (Event Handler)**:
```python
class EventBus:
    def __init__(self):
        self.handlers = {}

    def on(self, event_name):
        def decorator(func):
            self.handlers[event_name] = func
            return func
        return decorator

bus = EventBus()

@bus.on('user.created')
def handle_user_created(user):
    send_welcome_email(user)

@bus.on('order.placed')
def handle_order_placed(order):
    process_payment(order)
```

**Confidence**: High (0.8-0.9) for framework decorator patterns. Medium (0.6-0.7) for custom callback implementations.

### Template Method Pattern

Template method pattern detection identifies base classes with template methods that call abstract hook methods.

**Detection Criteria**:
- Base class with concrete methods (template methods)
- Abstract methods intended to be overridden (hook methods)
- Template method calls hook methods in a defined sequence
- Subclasses override hook methods but not template method

**Example**:
```python
from abc import ABC, abstractmethod

class DataProcessor(ABC):
    def process(self, data):
        """Template method defining the algorithm skeleton"""
        raw = self.load_data(data)
        validated = self.validate(raw)
        transformed = self.transform(validated)
        self.save(transformed)

    @abstractmethod
    def load_data(self, source):
        """Hook: Load data from source"""
        pass

    @abstractmethod
    def validate(self, data):
        """Hook: Validate data"""
        pass

    def transform(self, data):
        """Hook: Transform data (optional override)"""
        return data

    @abstractmethod
    def save(self, data):
        """Hook: Save processed data"""
        pass

class CSVProcessor(DataProcessor):
    def load_data(self, source):
        return read_csv(source)

    def validate(self, data):
        return [row for row in data if row]

    def save(self, data):
        write_csv('output.csv', data)
```

**Confidence**: Medium (0.7-0.8) based on combination of abstract and concrete methods in base class.

### Dependency Injection Pattern

Dependency injection pattern detection identifies classes that receive dependencies through constructors or setters rather than creating them internally.

**Detection Criteria**:
- Constructor parameters accepting interface/protocol types
- Setter methods for injecting dependencies
- Optional dependencies with default values
- Absence of hard-coded object instantiation inside the class

**Example (Constructor Injection)**:
```python
class UserService:
    def __init__(self,
                 user_repository: UserRepository,
                 email_service: EmailService,
                 logger: Logger):
        self.user_repo = user_repository
        self.email_service = email_service
        self.logger = logger

    def create_user(self, username, email):
        user = self.user_repo.create(username, email)
        self.email_service.send_welcome(email)
        self.logger.info(f"Created user: {username}")
        return user
```

**Example (Setter Injection)**:
```python
class ReportGenerator:
    def __init__(self):
        self.data_source = None
        self.formatter = None

    def set_data_source(self, source):
        self.data_source = source

    def set_formatter(self, formatter):
        self.formatter = formatter

    def generate(self):
        data = self.data_source.fetch()
        return self.formatter.format(data)
```

**Confidence**: Medium (0.65-0.75) based on constructor signatures and absence of direct instantiation.

## Internal Pattern Detection

Debtmap also detects certain patterns internally for analysis purposes, but these are not exposed as user-facing design pattern detection features. These internal patterns help improve the accuracy of other analyses like god object detection and complexity calculations.

### Builder Pattern (Internal Use Only)

The Builder pattern is detected internally during **god object detection** to avoid false positives. Classes that follow the builder pattern are given adjusted scores in god object analysis since builder classes naturally have many methods and fields.

**Note**: Builder pattern detection is **not available** via the `--patterns` CLI flag. It's used only internally for scoring adjustments.

**Internal Detection Criteria**:
- Struct with builder suffix or builder-related naming
- Methods returning `Self` for chaining
- Final `build()` method returning the constructed type
- Type-state pattern usage (optional)

**Example** (Internal Detection):
```rust
pub struct HttpClientBuilder {
    base_url: Option<String>,
    timeout: Duration,
    headers: HashMap<String, String>,
}

impl HttpClientBuilder {
    pub fn new() -> Self { /* ... */ }

    // Chaining methods detected internally
    pub fn base_url(mut self, url: impl Into<String>) -> Self { /* ... */ }
    pub fn timeout(mut self, timeout: Duration) -> Self { /* ... */ }
    pub fn header(mut self, key: String, value: String) -> Self { /* ... */ }

    pub fn build(self) -> Result<HttpClient> { /* ... */ }
}
```

**Why Internal Only**: Builder patterns are a legitimate design choice for complex object construction. Debtmap detects them to prevent flagging builder classes as god objects, but doesn't report them as design patterns since they don't require complexity adjustments like other patterns.

**Source**: `src/organization/builder_pattern.rs` - Used for god object detection score adjustment

### Visitor Pattern (Internal Use Only)

The Visitor pattern is detected internally for **complexity analysis normalization**. When exhaustive pattern matching is detected (typical of visitor patterns), Debtmap applies logarithmic complexity scaling instead of linear scaling to avoid penalizing idiomatic exhaustive match expressions.

**Note**: Visitor pattern detection is **not available** via the `--patterns` CLI flag. It's used only internally for complexity scaling adjustments.

**Internal Detection Criteria**:
- Trait with visit methods for different types
- Implementations providing behavior for each visited type
- Exhaustive pattern matching across enum variants
- Used primarily for AST traversal or data structure processing

**Example** (Internal Detection):
```rust
trait Visitor {
    fn visit_function(&mut self, func: &Function);
    fn visit_class(&mut self, class: &Class);
    fn visit_module(&mut self, module: &Module);
}

impl Visitor for ComplexityVisitor {
    fn visit_function(&mut self, func: &Function) {
        // Exhaustive matching detected for complexity scaling
        match &func.body {
            FunctionBody::Simple => { /* ... */ }
            FunctionBody::Complex(statements) => { /* ... */ }
        }
    }
}
```

**Why Internal Only**: Visitor patterns often involve exhaustive pattern matching which can appear complex by traditional metrics. Debtmap detects these patterns to apply logarithmic scaling (`log2(match_arms) * avg_complexity`) instead of linear, preventing false positives in complexity analysis. This is a complexity adjustment mechanism, not a user-visible pattern detection feature.

**Source**: `src/complexity/visitor_detector.rs` - Used for complexity analysis, not pattern reporting

## Configuration

### Current Implementation Status

Pattern detection is currently **internal-only** and used for analysis adjustments. The CLI flags for pattern detection exist in the codebase but are not yet fully integrated into the analysis pipeline.

**Status Summary**:
- ✅ Pattern detection logic implemented (7 user-facing patterns)
- ✅ CLI flags defined (`--no-pattern-detection`, `--patterns`, `--pattern-threshold`, `--show-pattern-warnings`)
- ⚠️ CLI flags not yet wired to analysis pipeline
- ⚠️ Pattern detection results not currently exposed in output formats

Pattern detection is primarily used internally for:
- Adjusting complexity scores to avoid false positives
- Informing god object detection (Builder pattern)
- Normalizing exhaustive pattern matching complexity (Visitor pattern)

### CLI Options (Defined but Not Yet Active)

The following CLI flags are defined in the codebase (`src/cli.rs:228-241`) but are not yet fully integrated:

```bash
# Disable all pattern detection (planned)
debtmap analyze . --no-pattern-detection

# Enable only specific patterns (planned)
debtmap analyze . --patterns observer,singleton,factory,strategy,callback,template_method,dependency_injection

# Set confidence threshold (planned)
debtmap analyze . --pattern-threshold 0.8

# Show warnings for uncertain pattern detections (planned)
debtmap analyze . --show-pattern-warnings
```

**Planned Patterns for `--patterns` Flag** (when integration is complete):
- `observer` - Observer pattern detection
- `singleton` - Singleton pattern detection
- `factory` - Factory pattern detection
- `strategy` - Strategy pattern detection
- `callback` - Callback pattern detection
- `template_method` - Template method pattern detection
- `dependency_injection` - Dependency injection detection

**Note**: Builder and Visitor patterns are detected internally but will not be available via the `--patterns` flag. See [Internal Pattern Detection](#internal-pattern-detection) for details.

### Roadmap: Pattern Detection Output

When fully integrated, pattern detection results will appear in debtmap's output formats:

**Planned Terminal Format**:
```
Design Patterns Detected:
  Observer Pattern (confidence: 0.88)
    Interface: EventListener (event_system.py:4)
    Implementations: AuditLogger, SessionManager
```

**Planned JSON Format**:
```json
{
  "pattern_instances": [
    {
      "pattern_type": "Observer",
      "confidence": 0.88,
      "location": "event_system.py:4",
      "implementations": ["AuditLogger", "SessionManager"]
    }
  ]
}
```

**Current Workaround**: Pattern detection is used internally during analysis to improve accuracy. To see the effects of pattern detection:
1. Run analysis with and without `--no-pattern-detection` (when implemented)
2. Compare complexity scores and god object detection results
3. Patterns are being detected, but not explicitly reported in output

## Confidence Scoring

Pattern detection uses a confidence scoring system (0.0-1.0) to indicate match quality:

- **0.9-1.0**: Very High - Strong structural match with all key elements present
- **0.8-0.9**: High - Clear pattern with most elements present
- **0.7-0.8**: Medium-High - Pattern present with some uncertainty
- **0.6-0.7**: Medium - Possible pattern with limited evidence
- **0.5-0.6**: Low - Weak match, may be false positive

**Default Threshold**: 0.7 - Only patterns with 70% or higher confidence are reported by default.

**Adjusting Thresholds**:
```bash
# More strict (fewer patterns, higher confidence)
debtmap analyze . --pattern-threshold 0.85

# More lenient (more patterns, lower confidence)
debtmap analyze . --pattern-threshold 0.6 --show-pattern-warnings
```

**How Confidence is Calculated**:

Each pattern detector calculates confidence holistically based on multiple factors:

1. **Structural completeness**: Are all expected elements present?
2. **Naming conventions**: Do names match expected patterns?
3. **Implementation count**: Are there enough implementations to confirm the pattern?
4. **Cross-validation**: Do different detection heuristics agree?

For example, Observer pattern confidence is calculated holistically based on:
- Presence of abstract base class with appropriate markers (`ABC`, `Protocol`, etc.)
- Number of concrete implementations found
- Detection of registration methods (`add_observer`, `register`, `subscribe`)
- Detection of notification methods (`notify`, `notify_all`, `trigger`, `emit`)
- Naming conventions matching observer patterns

Higher confidence requires more structural elements to be present. The calculation is not a simple sum of individual weights but rather a holistic assessment of pattern completeness.

## Cross-File Pattern Detection

Debtmap can detect patterns that span multiple files, particularly for the Observer pattern where interfaces and implementations may be in separate modules.

**How Cross-File Detection Works**:

1. **Import Tracking**: Debtmap tracks imports to understand module dependencies
2. **Interface Registry**: Abstract base classes are registered globally
3. **Implementation Matching**: Implementations in other files are matched to registered interfaces
4. **Cross-Module Context**: A shared context links related files

**Example**:

```python
# interfaces/observer.py
from abc import ABC, abstractmethod

class EventObserver(ABC):
    @abstractmethod
    def on_event(self, data):
        pass

# observers/logging_observer.py
from interfaces.observer import EventObserver

class LoggingObserver(EventObserver):
    def on_event(self, data):
        log(data)

# observers/email_observer.py
from interfaces.observer import EventObserver

class EmailObserver(EventObserver):
    def on_event(self, data):
        send_email(data)
```

Debtmap detects this as a single Observer pattern with cross-file implementations.

**Limitations**:
- Only works for explicitly imported interfaces
- Requires static import analysis (dynamic imports may not be tracked)
- Most effective within a single project (not across external dependencies)

## Rust-Specific Pattern Detection

### Trait-Based Patterns

Rust pattern detection leverages the trait system for identifying patterns:

**Trait Registry**: Tracks trait definitions and implementations across modules
```rust
// Trait registered for pattern detection
pub trait EventHandler {
    fn handle(&self, event: &Event);
}

// Multiple implementations tracked
impl EventHandler for LogHandler { /* ... */ }
impl EventHandler for MetricsHandler { /* ... */ }
impl EventHandler for AlertHandler { /* ... */ }
```

**Observer Pattern via Traits**:
```rust
pub trait Observable {
    fn subscribe(&mut self, observer: Box<dyn Observer>);
    fn notify(&self, event: &Event);
}

pub trait Observer {
    fn on_event(&self, event: &Event);
}
```

**Differences from Python Detection**:
- Traits are more explicit than Python's ABC
- Type system ensures implementation correctness
- No runtime reflection needed for detection
- Pattern matching exhaustiveness helps identify Visitor pattern

## Integration with Complexity Analysis

Debtmap has two separate but complementary systems for patterns:

### 1. Design Pattern Detection (This Feature)

The 7 user-facing design patterns documented in this chapter (Observer, Singleton, Factory, Strategy, Callback, Template Method, Dependency Injection) are **detected and reported** to users. These patterns appear in the output to document architectural choices but do not directly adjust complexity scores.

**Purpose**: Architectural documentation and pattern identification

**Output**: Pattern instances with confidence scores in terminal, JSON, and markdown formats

### 2. Complexity Pattern Adjustments (Internal System)

Debtmap has a separate internal system in `src/complexity/python_pattern_adjustments.rs` that detects specific complexity patterns and applies multipliers. These are **different patterns** from the user-facing design patterns:

**Internal complexity patterns include**:
- Dictionary Dispatch (0.5x multiplier)
- Strategy Pattern detection via conditionals (0.6x multiplier)
- Comprehension patterns (0.8x multiplier)
- Other Python-specific complexity patterns

**Purpose**: Adjust complexity scores to avoid penalizing idiomatic code

**Output**: Applied automatically during complexity calculation, not reported separately

### Relationship Between the Systems

Currently, these are **independent systems**:
- Design pattern detection focuses on architectural patterns
- Complexity adjustments focus on implementation patterns

The design pattern detection results are primarily for documentation and architectural insights. The complexity scoring uses its own pattern recognition to apply appropriate adjustments.

### Visitor Pattern Special Case

The Visitor pattern (internal-only) is used for complexity analysis. When exhaustive pattern matching is detected, debtmap applies **logarithmic scaling**:

```
visitor_complexity = log2(match_arms) * average_arm_complexity
```

This prevents exhaustive pattern matching from being flagged as overly complex. See [Visitor Pattern (Internal Use Only)](#visitor-pattern-internal-use-only) for more details.

**See Also**:
- [Complexity Analysis]./analysis-guide/complexity-metrics.md - How complexity is calculated
- [Scoring Strategies]./scoring-strategies.md - Complexity adjustments and multipliers

## Practical Examples

### Example 1: Observer Pattern Code Structure

Pattern detection identifies Observer implementations even though results are not yet shown in output:

```python
# event_system.py
from abc import ABC, abstractmethod

class EventListener(ABC):
    @abstractmethod
    def on_user_login(self, user):
        pass

class AuditLogger(EventListener):
    def on_user_login(self, user):
        audit_log.write(f"User {user.id} logged in")

class SessionManager(EventListener):
    def on_user_login(self, user):
        create_session(user)

class EventDispatcher:
    def __init__(self):
        self.listeners = []

    def add_listener(self, listener):
        self.listeners.append(listener)

    def notify_login(self, user):
        for listener in self.listeners:
            listener.on_user_login(user)
```

**Current Behavior**: Debtmap internally detects this Observer pattern (confidence ~0.88) and uses it to adjust complexity scoring. The pattern structure is recognized but not reported in output.

**Source**: Pattern detection logic in `src/analysis/patterns/observer.rs`

### Example 2: Factory Pattern Detection Criteria

Debtmap detects factory patterns based on naming and structure:

```python
def create_logger(log_type: str):
    """Factory function - detected by 'create_' prefix"""
    if log_type == "file":
        return FileLogger()
    elif log_type == "console":
        return ConsoleLogger()
    else:
        return NetworkLogger()
```

**Current Behavior**: The factory pattern detector (in `src/analysis/patterns/factory.rs`) identifies this as a Factory pattern with medium-high confidence (~0.75-0.85) based on:
- Function name contains `create_`
- Returns different types based on parameter
- Multiple instantiation paths

This information is used internally to adjust complexity scores for factory functions.

### Example 3: Impact on Complexity Analysis

While pattern detection results aren't directly shown, their effect can be observed:

```bash
# Run standard analysis
debtmap analyze myapp/

# When --no-pattern-detection is fully integrated, compare results
# (currently this flag exists but isn't fully wired)
```

**Expected Differences**:
- Factory functions: Lower complexity scores with pattern detection
- Observer implementations: Adjusted scores for callback registration
- Template methods: Reduced penalty for abstract method patterns
- Builder classes: Not flagged as god objects despite many methods

## Use Cases

### 1. False Positive Reduction (Active)

**Problem**: Complex factory functions flagged as too complex
**Solution**: Pattern detection automatically adjusts complexity scores for recognized factory patterns

**Current Behavior**:
```bash
debtmap analyze myapp/
```

Factory functions are automatically detected and receive adjusted complexity scores. This happens internally without requiring specific flags.

**Source**: `src/analysis/patterns/factory.rs` applies multipliers to factory function complexity

### 2. Builder Pattern God Object Prevention (Active)

**Problem**: Builder classes flagged as god objects due to many chaining methods
**Solution**: Builder pattern detection automatically excludes builder classes from god object analysis

**Current Behavior**:
```rust
// This builder class is automatically recognized
pub struct HttpClientBuilder {
    // Many fields and methods
    pub fn base_url(mut self, url: String) -> Self { /* ... */ }
    pub fn timeout(mut self, duration: Duration) -> Self { /* ... */ }
    pub fn build(self) -> HttpClient { /* ... */ }
}
```

Debtmap detects the builder pattern (chaining methods returning `Self`, final `build()` method) and adjusts scoring accordingly.

**Source**: `src/organization/builder_pattern.rs` for god object detection adjustment

### 3. Future Use Case: Architecture Documentation (Planned)

**Problem**: Undocumented design patterns in legacy codebase
**Solution**: When pattern output is integrated, users will be able to generate architectural pattern reports

**Command**:
```bash
debtmap analyze . --show-pattern-warnings --format json > architecture-report.json
```

**Current Workaround**: Review complexity adjustments and god object scoring to infer where patterns are detected

### 4. Future Use Case: Pattern Consistency Validation (Planned)

**Problem**: Inconsistent Observer implementations across the codebase
**Solution**: When integrated, users can filter analysis to specific pattern types

**Command**:
```bash
debtmap analyze . --patterns observer --format json > observers.json
```

**Current Status**: Pattern detection logic exists and works internally, but results aren't yet exposed in output

## Troubleshooting

### Pattern Detection Not Visible in Output

**Symptoms**: Cannot see detected patterns in analysis output

**Explanation**: Pattern detection is currently **internal-only**. Patterns are detected and used to adjust complexity scoring, but results are not exposed in terminal, JSON, or markdown output.

**Current Behavior**:
- Patterns ARE being detected (see `src/analysis/patterns/mod.rs`)
- Detection results affect complexity scores and god object analysis
- Pattern information is not included in output formatting

**Solution**: To benefit from pattern detection:
1. Run standard analysis - patterns are automatically detected
2. Check if complexity scores seem adjusted for factory/callback patterns
3. Verify builder classes aren't flagged as god objects

**Future Integration**: CLI flags and output formatting will be connected when pattern output integration is complete.

### CLI Flags Have No Effect

**Symptoms**: Using `--patterns`, `--pattern-threshold`, or `--show-pattern-warnings` doesn't change results

**Explanation**: These CLI flags are defined in `src/cli.rs:228-241` but are not yet fully wired to the analysis pipeline.

**Current Status**:
- ✅ CLI argument parsing works
- ⚠️ Values not passed to pattern detector
- ⚠️ Pattern detection runs with default settings regardless of flags

**Workaround**: Pattern detection runs automatically with default settings (threshold 0.7, all 7 patterns enabled).

### Builder or Visitor Pattern Not Available via CLI

**Symptoms**: Cannot specify `--patterns builder` or `--patterns visitor`

**Explanation**: Builder and Visitor patterns are **intentionally internal-only** and will not be available as user-facing pattern detection features:
- **Builder**: Used during god object detection to adjust scores for builder classes (see `src/organization/builder_pattern.rs`)
- **Visitor**: Used for complexity analysis to apply logarithmic scaling to exhaustive match expressions (see `src/complexity/visitor_detector.rs`)

**Solution**: These patterns are automatically detected when needed for internal analyses. They won't appear in the `--patterns` flag even when that feature is fully integrated.

**Available user-facing patterns**: `observer`, `singleton`, `factory`, `strategy`, `callback`, `template_method`, `dependency_injection`

### False Positive Complexity Adjustments

**Symptoms**: Function with `create_` prefix gets lower complexity score but isn't actually a factory

**Possible Causes**:
1. Naming collision (e.g., `create_session()` that doesn't create objects)
2. Overly broad pattern matching heuristics

**Current Workaround**: Pattern detection cannot currently be disabled or tuned per-file. The `--no-pattern-detection` flag exists but isn't yet wired to the detector.

**Future Solution**: When CLI integration is complete:
```bash
debtmap analyze . --no-pattern-detection  # Disable all pattern detection
debtmap analyze . --pattern-threshold 0.9  # Require very high confidence
```

## Best Practices

### Current Recommendations

1. **Trust automatic detection**: Pattern detection runs automatically with sensible defaults (threshold 0.7, all 7 patterns enabled)
2. **Review complexity scores**: Lower-than-expected complexity for factory/callback functions indicates pattern detection is working
3. **Check builder classes**: If builder classes aren't flagged as god objects, builder pattern detection is working correctly
4. **Follow pattern idioms**: Use standard naming conventions (`create_`, `make_`, `@abstractmethod`, etc.) to ensure patterns are recognized
5. **Structure code clearly**: Well-structured patterns (clear base classes, explicit implementations) have higher confidence scores

### When CLI Integration is Complete

Future best practices when CLI flags are fully wired:

1. **Start with defaults**: The default 0.7 threshold will work well for most projects
2. **Use `--show-pattern-warnings`** during initial analysis to see borderline detections
3. **Tune thresholds per-project**: Adjust `--pattern-threshold` based on your codebase's idioms
4. **Disable selectively**: Use `--no-pattern-detection` to compare scores with/without adjustments
5. **Review pattern reports**: Examine detected patterns to understand architectural decisions

## Summary

### Current State

Debtmap's design pattern detection **exists and works internally** with the following characteristics:

**Implemented Features**:
- **7 user-facing patterns**: Observer, Singleton, Factory, Strategy, Callback, Template Method, Dependency Injection
-**2 internal patterns**: Builder (for god object detection), Visitor (for complexity normalization)
-**Pattern detection logic**: Fully implemented in `src/analysis/patterns/`
-**Confidence scoring**: 0.0-1.0 scale with holistic assessment
-**Cross-file detection**: Tracks imports and interfaces across modules
-**Rust trait support**: Leverages trait system for pattern detection
-**Complexity integration**: Automatically adjusts scores to reduce false positives

**Partially Implemented**:
- ⚠️ **CLI flags**: Defined in `src/cli.rs` but not wired to pattern detector
- ⚠️ **Output formatting**: `PatternInstance` type exists but not exposed in output

**Not Yet Implemented**:
- **Pattern output in terminal/JSON/markdown**: Detection results not shown to users
-**User configuration**: Cannot currently control pattern detection via CLI or config file
-**Pattern-specific reports**: Cannot filter or focus on specific pattern types

### Impact

Pattern detection **significantly improves analysis accuracy** even without visible output:
- **Reduces false positives**: Factory functions, callbacks, and template methods get appropriate complexity scores
- **Prevents god object misclassification**: Builder classes recognized and excluded from god object detection
- **Normalizes exhaustive matching**: Visitor pattern detection applies logarithmic scaling to pattern matching
- **Supports multiple languages**: Works across Python, JavaScript, TypeScript, and Rust

### Future Integration

When CLI and output integration is complete, users will be able to:
- View detected patterns in analysis output
- Control pattern detection via `--patterns`, `--pattern-threshold`, and `--show-pattern-warnings` flags
- Generate architectural documentation from pattern detection results
- Validate pattern consistency across codebases

The foundation is solid - pattern detection works correctly and provides value. The remaining work is connecting the detection logic to user-facing configuration and output.