Skip to content

Commit af0345e

Browse files
committed
Feature/Add documentation for named parameter and union type support in factory methods
1 parent 3954b1e commit af0345e

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ On top of those base traits **Complex Heart** provide ready to use compositions:
3030

3131
- **Type-Safe Factory Method**: The `make()` static factory validates constructor parameters at runtime with clear error messages
3232
- **Automatic Invariant Checking**: When using `make()`, Value Objects and Entities automatically validate invariants after construction (no manual `$this->check()` needed)
33+
- **Named Parameter Support**: Full support for PHP 8.0+ named parameters for improved readability and flexibility
34+
- **Union Type Support**: Complete support for PHP 8.0+ union types (e.g., `int|float`, `string|null`)
3335
- **Readonly Properties Support**: Full compatibility with PHP 8.1+ readonly properties
3436
- **PHPStan Level 8**: Complete static analysis support
3537

wiki/Domain-Modeling-Aggregates.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,14 @@ final class Order implements Aggregate
8787

8888
**Benefits of using `make()` in factory methods:**
8989
- Automatic invariant checking when using `make()`
90-
- Type validation at runtime
90+
- Type validation at runtime with clear error messages
91+
- Named parameter support for improved readability (as shown above)
92+
- Union type support (e.g., `int|float`, `string|null`)
9193
- Cleaner factory method code
9294
- Consistent with Value Objects and Entities
9395

96+
**Why named parameters?** As shown in the example above, using named parameters (`reference:`, `customer:`, etc.) makes the code self-documenting and prevents parameter mix-ups, especially important in Aggregates with many constructor parameters.
97+
9498
**Important:** Auto-check ONLY works when using `make()`. In the alternative approach using direct constructor calls, you must manually call `$this->check()` inside the constructor.
9599

96100
#### Alternative: Direct Constructor with Manual Check

wiki/Domain-Modeling-Entities.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,19 @@ final class Customer implements Entity
4949

5050
// Type-safe instantiation with automatic invariant validation
5151
$customer = Customer::make(UUIDValue::random(), 'Vincent Vega');
52+
53+
// Named parameters for improved readability (PHP 8.0+)
54+
$customer = Customer::make(
55+
id: UUIDValue::random(),
56+
name: 'Vincent Vega'
57+
);
5258
```
5359

5460
**Benefits:**
5561
- Automatic invariant checking when using `make()`
56-
- Type validation at runtime
62+
- Type validation at runtime with clear error messages
63+
- Named parameter support for improved readability
64+
- Union type support (e.g., `int|float`, `string|null`)
5765
- Cleaner constructor code
5866

5967
**Important:** Auto-check ONLY works when using `make()`. If you call the constructor directly (`new Customer(...)`), you must manually call `$this->check()` inside the constructor.

wiki/Domain-Modeling-Value-Objects.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,53 @@ class Email implements ValueObject
9292
$email = Email::make('user@example.com'); // ✅ Valid
9393
$email = Email::make(123); // ❌ TypeError: parameter "value" must be of type string, int given
9494
$email = Email::make('invalid'); // ❌ InvariantViolation: Valid format
95+
96+
// Named parameters for improved readability (PHP 8.0+)
97+
$email = Email::make(value: 'user@example.com'); // ✅ Self-documenting code
9598
```
9699

97100
**Benefits of `make()`:**
98101
- Runtime type validation with clear error messages
99102
- Automatic invariant checking after construction
103+
- Named parameter support for improved readability
104+
- Union type support (e.g., `int|float`, `string|null`)
100105
- Works seamlessly with readonly properties
101106
- PHPStan level 8 compliant
102107

103108
**Important:** Auto-check ONLY works when using `make()`. Direct constructor calls do NOT trigger automatic invariant checking, so you must manually call `$this->check()` in the constructor.
104109

110+
#### Named Parameters Example
111+
112+
Named parameters (PHP 8.0+) make code more readable and allow parameters in any order:
113+
114+
```php
115+
final class Money implements ValueObject
116+
{
117+
use IsValueObject;
118+
119+
public function __construct(
120+
private readonly int|float $amount,
121+
private readonly string $currency
122+
) {}
123+
124+
protected function invariantPositiveAmount(): bool
125+
{
126+
return $this->amount > 0;
127+
}
128+
129+
public function __toString(): string
130+
{
131+
return sprintf('%s %s', $this->amount, $this->currency);
132+
}
133+
}
134+
135+
// All equivalent, choose the most readable for your context:
136+
$money = Money::make(100, 'USD'); // Positional
137+
$money = Money::make(amount: 100, currency: 'USD'); // Named
138+
$money = Money::make(currency: 'USD', amount: 100); // Named, different order
139+
$money = Money::make(100, currency: 'USD'); // Mixed
140+
```
141+
105142
#### Alternative: Constructor Property Promotion with Manual Check
106143

107144
If you prefer direct constructor calls, you **must** manually call `$this->check()`:

0 commit comments

Comments
 (0)