Skip to content

Innlegg

Kodifisering av den hemmelige sausen

16. september 2019 • 5 min lesing

Kodifisering av den hemmelige sausen

Hver applikasjon har sin hemmelige saus, sin grunn til å eksistere. Kodifisering av den hemmelige sausen er avgjørende for å skrive vedlikeholdbare og vellykkede applikasjoner.

Vent. Hva er kodifisering? Tålmodighet min venn, vi kommer dit.

La oss først lage en hypotese:

Du har nettopp blitt forfremmet til Lead Software Engineer (Gratulerer!). Din CEOs første oppgave er å lage et nytt produkt for selskapet. Det er en regnskapsapplikasjon fra bunnen av. Ledelsen føler at å ha en tilpasset regnskapsløsning vil gi dem et fortrinn over konkurrentene.

Noen måneder har gått, de fleste av de tverrgående bekymringene er utviklet (hurra for deg!). Teamet fokuserer nå på den deilige godheten i applikasjonen: forretningsdomenet (den hemmelige sausen). Det er her kodifiseringen av den hemmelige sausen begynner.

Kodifisering er å sette struktur rundt et essensielt konsept i forretningsdomenet.

I regnskap er pris (P) inntjening (E) forholdet (P/E-forhold) et mål på inntjening for et selskap. Et høyt P/E-forhold antyder høy inntjeningsvekst i fremtiden. P/E-forholdet beregnes ved å ta markedsverdien per aksje (aksjekurs) delt på inntjening per aksje (fortjeneste – utbytte / # utestående aksjer).

En enkel, og jeg vil hevde, naiv implementering:

public class Metric
{
    public string Name { get; set; }
    public decimal Value {get; set}
    public int Order {get; set;}
}
public class AccountingSummary
{
    public Metric[] GetMetrics(decimal price, decimal earnings)
    {
        var priceEarningsRatio = price/earnings;
        
        var priceEarningsRatioMetric = new Metric 
        {
            Name = "P/E Ratio",
            Value = priceEarningsRatio,
            Order = 0
        }
        return new [] {priceEarningsRatioMetric};
    }
}

Hvis dette bare brukes ett sted, er dette greit. Hva hvis du bruker P/E-forholdet i andre områder?

Som her i PriceEarnings.cs

var priceEarningsRatio = price/earnings;

Og her i AccountSummary.cs

var priceEarningsRatio = price/earnings;

Og her borte i StockSummary.cs

var priceEarningsRatio = price/earnings;

P/E-forholdet er kjernen i denne applikasjonen, men hvordan det er implementert, hardkodet på forskjellige steder, gjør at viktigheten av P/E-forholdet går tapt i et hav av kode. Det er bare et annet tre i skogen.

Du åpner også for risikoen for å endre forholdet ett sted, men ikke det andre. Dette kan kaste av seg nedstrøms beregninger. Disse typene feil er notorisk vanskelige å finne.

Ofte vil testere anta at hvis det fungerer i ett område, er det korrekt i alle områder. Hvorfor skulle ikke applikasjonen bruke samme kode til å generere P/E-forholdet for hele applikasjonen? Er ikke dette poenget med objektorientert programmering?

Jeg kan forestille meg en feil som dette som kommer i produksjon og ikke oppdages før et besøk fra din leder som krever å vite hvorfor SECs P/E-forhold beregninger er forskjellige fra det selskapet arkiverte. Det er ikke et flott sted å være.

La oss se på vår P/E-forhold implementering på nytt og se hvordan vi kan forbedre vårt første forsøk.

I regnskapssystemer er formler en ting, la oss sette struktur rundt formler ved å legge til et grensesnitt:

public interface IFormula
{
    decimal Calculate<T>(T model);
}

Hver formel er nå implementert med dette grensesnittet som gir oss konsistens og forutsigbarhet.

Her er vårt forbedrede P/E-forhold etter å ha implementert vårt grensesnitt:

Vi har lagt til en PriceEarningsModel for å sende de nødvendige dataene inn i vår Calculate-metode.

public class PriceEarningsModel
{
    public decimal Price {get; set;}
    public decimal Earnings {get; set;}
}

Ved å bruke vår PriceEarningsModel, har vi laget en implementering av IFormula-grensesnittet for P/E-forholdet.

public class PriceEarningsRatioFormula : IFormula
{
    public decimal Calculate<PriceEarningsModel>(PriceEarningsModel model)
    {
        return model.Price / model.Earnings;
    }
}

Vi har nå kodifisert P/E-forholdet. Det er et førsteklasses konsept i vår applikasjon. Vi kan bruke det hvor som helst. Det er testbart, og en endring påvirker hele applikasjonen.

Som en påminnelse, her er implementeringen vi begynte med:

public class Metric
{
    public string Name { get; set; }
    public decimal Value {get; set}
    public int Order {get; set;}
}
public class AccountingSummary
{
    public Metric[] GetMetrics(decimal price, decimal earnings)
    {
        var priceEarningsRatio = price/earnings;
        
        var priceEarningsRatioMetric = new Metric 
        {
            Name = "P/E Ratio",
            Value = priceEarningsRatio,
            Order = 0
        }
        return new [] {priceEarningsRatioMetric};
    }
}

Det er enkelt og får jobben gjort. Problemet er at P/E-forholdet, som er et kjernekonsept i vår regnskapsapplikasjon, ikke skiller seg ut. Ingeniører som ikke er kjent med applikasjonen eller forretningsdomenet vil ikke forstå viktigheten.

Vår forbedrede implementering bruker vår nye P/E-forhold klasse. Vi injiserer PriceEarningsRatioFormula-klassen inn i vår AccountSummary-klasse.

Vi erstatter vårt hardkodede P/E-forhold med vår nye PriceEarningsRatioFormula-klasse.

public class AccountingSummary
{
    private PriceEarningsRatioFormula _peRatio;
    
    public AccountingSummary(PriceEarningsRatioFormula peRatio)
    {
        _peRatio = peRatio;
    }
    
    public Metric[] GetMetrics(decimal price, decimal earnings)
    {
        var priceEarningsRatio = _peRatio.Calculate(new PriceEarningsModel 
        { 
            Price = price, 
            Earnings = earnings
        });
        
        var priceEarningsRatioMetric = new Metric 
        {
            Name = "P/E Ratio",
            Value = priceEarningsRatio,
            Order = 0
        }
        return new [] {priceEarningsRatioMetric};
    }
}

Man kan hevde at det er litt mer løfting med PriceEarningsRationFormula over den forrige implementeringen og jeg ville være enig. Det er litt mer seremoni, men fordelene er vel verdt den lille økningen i kode og seremoni.

Først får vi muligheten til å endre P/E-forholdet for hele applikasjonen. Vi har også en enkelt implementering å feilsøke hvis defekter oppstår.

Til slutt har vi kodifisert konseptet med PriceEarningsRatioFormula i applikasjonen. Når en ny ingeniør blir med på teamet, vil de vite at formler er essensielle for applikasjonen og forretningsdomenet.

Det finnes andre metoder for kodifisering (innkapsling) av domenet, som mikrotjenester og assemblies. Hver tilnærming har sine fordeler og ulemper, du og teamet ditt må bestemme hva som er best for applikasjonen din.

Å innkapsle nøkkeldomene konsepter i klasser og grensesnitt skaper gjenbrukbare komponenter og konseptuelle grenser. Dette gjør en applikasjon lettere å resonnere med, reduserer defekter og senker barrierene for å ta inn nye ingeniører.

Forfatter: Chuck Conway spesialiserer seg på programvareutvikling og Generativ AI. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube.

↑ Tilbake til toppen

Du liker kanskje også