Ubiquitous Language

Domänstyrd design (DDD) är inget nytt ämne (Eric Evans formaliserade begreppet för mer än tio år sedan). Det är dock märkligt hur de grundläggande begreppen i ämnet än i dag väcker intresse, särskilt i .NET-communities. Ännu märkligare är hur samma begrepp misstolkas.

Grunden för DDD ligger i begreppet det allmängiltiga språket. Det ligger inte i att bestämma vad en entitet, ett värdeobjekt, ett aggregat, en tjänst eller ett arkiv är.

Intrycket vi får är att alla som börjar studera DDD läser de första sidorna i Evans-boken eller Vernon-boken och hoppar snabbt rakt över till sidorna som beskriver mönstren.

Vi pratar ofta med IT-personal som tror att ett definierat allmängiltigt språk innebär att namnen på klasser och egenskaper, skrivna av programmerare, överensstämmer med domänexperternas vokabulär. Detta är dock en grov förenkling.

För att förstå vikten av ett allmängiltigt språk kan vi börja med den ”enhet” som anges nedan:

public class Employee{ public string Id { get; set; } public string Name { get; set; } public string Cpf { get; set; } public decimal Salary { get; set; }}

Här är ett utmärkt exempel på ett anemiskt genomförande! Men innan du läser vidare ska du försöka lista ut varför.

I vårt dagliga arbete, när vi använder det här exemplet, får vi höra förslag om att den här klassen saknar beteenden (Vilket stämmer!). Men när vi frågar vad sådana ”beteenden” skulle vara, upptäcker vi att folk upprepar generiska argument (från personer som inte heller har ”fattat” idén) och inte kan identifiera vad som är fel!

Ett av de vanligaste argumenten är att egenskapsinställare bör vara privata. I stället borde vi ha ”DefineXXX”-metoder som skulle implementera valideringar. Denna idé är meningslös eftersom syftet med setters är just att fastställa värden för egenskaperna, och det skulle inte vara något problem att implementera valideringslogik i dem.

Entitetens metoder bör ange motivationen för dess tillståndsändringar. Dessutom måste det finnas minst en konstruktör som kan instantiera entiteten från början, i ett giltigt tillstånd.

Det är inte ovanligt att hitta klassimplementationer med egenskaper som t.ex. kontrollerar om det värde man försöker ställa in är non-null, även när samma egenskaper har null som standardvärde. Vad är logiken här?

Se ett annat exempel på en anemisk klass:

public class Customer { public string Name { get; private set; } public string Email { get; private set; } public DateTime BirthDate { get; private set; } public Customer(Guid id, string name, string email, DateTime birthDate) { Id = id; Name = name; Email = email; BirthDate = birthDate; } }

I klassen ovan har vi en typisk ”post” för en funktionell implementering. Men i ett objektorienterat språk är detta inte en entitet.

Den här idén skulle till och med vara vettig i ett rent funktionellt språk där ”entiteten” konceptuellt är utspridd i olika funktioner som definierar beteendet, men i C# är det inte alls vettigt.

Vi provar en andra version för klassen Employee:

public class Employee{ public string Id { get; private set; } public string Name { get; private set; } public string Cpf { get; private set; } public decimal Salary { get; private set; } public Employee(string name, string cpf) { //.. } public void RaiseSalary(decimal amount) { //.. }}

Den här gången är entiteten mindre anemisk. Trots allt är de motiv som driver ändringen av egenskapsvärden uppenbara. Lägg märke till hur till och med värdet av testskrivande blir tydligare.

När som helst har vi fortfarande problem. Vi namngav metoden ”RaiseSalary”, men det är inte så som domänexperter beskriver denna operation. Det enda sättet att definiera faktiska skäl för att ändra egenskapsvärden är att tala med dessa experter.

Att tänka på…

Identifiering och implementering av det allmängiltiga språket är inte bara till för att definiera klassnamn eller egenskaper. Det allmängiltiga språket måste avslöjas främst i motiveringarna för tillståndsändringarna av våra entiteter explicit.

Att förstå det allmängiltiga språket är mycket viktigare än att lära sig standarderna. Utan verklig kunskap om domänen är värdet av designmönster noll.

Sorg dig först om att lära dig det viktigaste. Ta tid och anstränga dig för att förstå domänen väl och stava ut dess allmängiltiga språk. Då kan det till och med vara vettigt att tänka på att associera DDD med mer avancerade tekniska begrepp.

Lämna ett svar

Din e-postadress kommer inte publiceras.