Avgränsade kontexter och kontextmappning
Dela upp stora domäner i avgränsade kontexter som kommunicerar säkert.
Avgränsade kontexter och kontextmappning är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.
Strategisk DDD
Taktiska mönster modellerar objekt inom en domän; strategisk DDD avgör hur ett stort system ska delas upp i delar som kan utvecklas oberoende av varandra. Det centrala begreppet är en avgränsad kontext — en tydlig gräns inom vilken en domänmodell och dess språk är konsekventa. Kontextkartläggning beskriver hur dessa kontexter förhåller sig till varandra. Detta har ofta större påverkan än utformningen av någon enskild klass.
Det gemensamma domänspråket
Inom en avgränsad kontext delar teamet ett gemensamt språk — samma termer används i samtal, kod och modell. Utmaningen är att ett ord kan betyda olika saker i olika kontexter. En Customer i Sales (leads, rabatter) är inte samma sak som en Customer i Support (ärenden, SLA:er). En avgränsad kontext gör den gränsen tydlig i stället för att tvinga fram en enda uppsvälld gemensam modell.
Samma ord, olika modeller
Samma affärsbegrepp får en kontextspecifik modell. En Product i Catalog bryr sig om beskrivningar och media; i Inventory handlar den om lager och plats. Varje kontext definierar endast det den behöver.
<?php
namespace Catalog;
final class Product {
public function __construct(
public readonly string $sku,
public readonly string $description
) {}
}
namespace Inventory;
final class Product {
public function __construct(
public readonly string $sku,
public readonly int $onHand
) {}
}
namespace App;
$c = new \Catalog\Product('A1', 'Blue mug');
$i = new \Inventory\Product('A1', 42);
echo $c->description, ' / ', $i->onHand, PHP_EOL;
Varför inte en enda stor modell
Att försöka få en enda kanonisk Customer att fungera för alla team leder till en god class med motstridiga krav, konkurrens mellan team och förändringar som lätt går sönder. Avgränsade kontexter låter varje team äga sin modell och sitt språk, distribuera oberoende av andra och översätta vid gränserna. Gränsen är platsen där ni betalar en liten integrationskostnad för att undvika en stor kostnad för kopplingar.
Kontextkartor
En kontextkarta är en övergripande bild av era avgränsade kontexter och relationerna mellan dem. Den dokumenterar både den tekniska integrationen och relationen mellan teamen och på det politiska planet (vem som är beroende av vem, vem som kan styra förändringar). DDD har namn på flera återkommande relationsmönster, som vi går igenom härnäst.
Conformist i kod
Relationer är ofta riktade — en uppströmskontext påverkar en nedströmskontext (Customer/Supplier, Conformist, Anticorruption Layer). En Conformist nedströms har inget förhandlingsutrymme och tar därför helt enkelt över uppströmskontextens modell som den är: den använder den främmande strukturen direkt och accepterar kopplingen.
<?php
// Upstream's shape, used verbatim downstream (Conformist)
final class UpstreamUser {
public function __construct(public readonly int $userId, public readonly string $login) {}
}
final class Greeter { // conforms: depends directly on upstream type
public function greet(UpstreamUser $u): string {
return "Hello {$u->login} (#{$u->userId})";
}
}
echo (new Greeter())->greet(new UpstreamUser(7, 'jane')), PHP_EOL;
Anticorruption Layer
En ACL översätter en extern eller äldre modell till kontextens rena modell, så att främmande begrepp aldrig läcker inåt. Det är Adapter-mönstret tillämpat vid en kontextgräns, som skyddar det gemensamma domänspråket.
<?php
// Our clean domain model
final class Customer {
public function __construct(public readonly string $id, public readonly string $name) {}
}
// Legacy/external shape we must not let leak in
$legacy = ['CUST_NO' => '0042', 'FULL_NM' => 'Jane Doe'];
final class LegacyCustomerAcl {
public function toDomain(array $row): Customer {
return new Customer($row['CUST_NO'], $row['FULL_NM']);
}
}
$customer = (new LegacyCustomerAcl())->toDomain($legacy);
echo $customer->id, ' ', $customer->name, PHP_EOL;
Shared Kernel i kod
- Shared Kernel: två kontexter delar en liten, gemensamt ägd delmängd (nedan en gemensam
Money-typ) — ändra den endast efter överenskommelse. - Partnership: två team lyckas eller misslyckas tillsammans.
- Separate Ways: integrationen är inte värd kostnaden.
- Open Host Service / Published Language: uppströms erbjuder ett stabilt, dokumenterat protokoll för många konsumenter.
<?php
namespace Shared; // small, jointly-owned kernel
final class Money {
public function __construct(public readonly int $cents, public readonly string $cur) {}
public function format(): string { return number_format($this->cents / 100, 2) . ' ' . $this->cur; }
}
namespace Billing; // depends on the shared kernel
use Shared\Money;
function invoiceTotal(): Money { return new Money(4999, 'USD'); }
namespace Payroll; // also depends on the SAME shared kernel
use Shared\Money;
function salary(): Money { return new Money(500000, 'USD'); }
Integrera kontexter i PHP
I praktiken integreras kontexter genom väldefinierade kontrakt: en översättande metod, en API-klient som kapslar in ett Published Language eller meddelanden. Den mottagande sidan mappar den främmande DTO:n till sin egen modell, så att kopplingen stannar vid gränsen.
<?php
// Published Language DTO from an upstream Open Host Service
final class PricingDto {
public function __construct(public readonly string $sku, public readonly int $cents) {}
}
// Our downstream model
final class CatalogPrice {
public function __construct(public readonly string $sku, public readonly float $amount) {}
}
final class PricingTranslator {
public function translate(PricingDto $dto): CatalogPrice {
return new CatalogPrice($dto->sku, $dto->cents / 100);
}
}
$p = (new PricingTranslator())->translate(new PricingDto('A1', 1599));
echo $p->amount, PHP_EOL; // 15.99
Kontexter och arkitektur
Avgränsade kontexter passar naturligt ihop med driftsenheter: en modulär monolit med tydliga modulgränser eller separata mikrotjänster. Gränsen bör dras runt affärsförmågan, inte runt tekniska lager. Mikrotjänster som delar upp en enda tätt kopplad kontext skapar en distribuerad monolit; väl avpassade kontextgränser skapar tjänster som kan förändras oberoende av varandra.
Händelser som skiljelinje
I praktiken är ett rent sätt för kontexter att integrera utan att dela modeller att utbyta händelser. Uppströms publicerar en liten, stabil händelse (ett Published Language); nedströms prenumererar och mappar den till sin egen modell — utan att någonsin importera uppströmsklasserna.
<?php
// Published Language: a minimal stable contract
final class OrderPlacedEvent {
public function __construct(public readonly string $orderId, public readonly int $cents) {}
}
// Downstream (Shipping context) maps it to its own model
final class Shipment {
public function __construct(public readonly string $forOrder) {}
}
final class ShippingListener {
public function on(OrderPlacedEvent $e): Shipment {
return new Shipment($e->orderId); // ignores fields it doesn't need
}
}
$shipment = (new ShippingListener())->on(new OrderPlacedEvent('o1', 1300));
echo 'shipment for ', $shipment->forOrder, PHP_EOL;
Snabbkontroll
Kontextrelationer.
Sammanfattning
Ni gick från taktisk till strategisk DDD. En avgränsad kontext är den gräns inom vilken en modell och dess gemensamma domänspråk förblir konsekventa, vilket befriar team från en enda uppsvälld gemensam modell. En kontextkarta dokumenterar relationerna — Customer/Supplier, Conformist, Anticorruption Layer, Shared Kernel, Partnership, Separate Ways, Open Host Service/Published Language — och fångar både teknisk integration och teamdynamik. Dra gränser runt affärsförmågor, översätt vid kanterna, så kan systemet utvecklas i delar som kan distribueras oberoende av varandra.
Lär dig PHP med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 49
- Lektioner
- 195
Vanliga frågor
Är lektionen ”Avgränsade kontexter och kontextmappning” gratis?
Ja – hela texten till ”Avgränsade kontexter och kontextmappning” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Avgränsade kontexter och kontextmappning”?
Dela upp stora domäner i avgränsade kontexter som kommunicerar säkert. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig PHP Academy?
Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Avgränsade kontexter och kontextmappning”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här PHP Academy-lektionen?
Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- DDD-byggblock: entiteter och värdeobjekt
- Aggregat, repositories och factories
- Domänhändelser och domäntjänster
- Avgränsade kontexter och kontextmappning