Hopp til innhold

Hvorfor generalisere systemer?

Når jeg snakker om 'generalisering', mener jeg det å trekke det generelle ut fra det spesielle, som å håndtere den visuelle representasjonen av en 'faktura' som et 'dokument' og en 'ansatt' som en 'person'.

Jeg mener at en systemutvikler eller hvem som helst som er del av designprosessen alltid bør alltid gjøre en analyse av hvorvidt en dataenhet eller en handling er spesiell for det konkrete tilfellet eller om den kan anses som del av et mer generelt domene. Te fakturaen - åpenbart en ikke-diskuterbar enhet i ethvert system som fakturerer kunder, og i denne forstand fortjener den en egen klasse og bør ikke håndteres som noe annet enn 'faktura'. Men deler av systemet håndterer dokumentproduksjon, konvertering mellom formater, publisering/ditribusjon - og for disse vil 'dokument' være et bedre begrep.

Illustrasjon (pseudokode):

Ha overbærenhet med meg i disse eksemplene, min intensjon har ikke vært å foreslå et rammeverk for en virkelig applikasjon... heller det å illustrere poenget med generalisering:

Ugeneralisert:

function bill(orderId) 
  createInvoice(orderId) -> returns invoiceId
  invoiceToPdf(invoiceId) -> returns pdf
  saveInvoice(invoiceId, pdf, 'invoice_12345.pdf')
  sendInvoice(invoiceId)

Generalisert:

function bill(orderId)
  createInvoice(orderId) -> returns invoiceId
  createReport('invoice', invoiceId, 'pdf') -> returns pdf
  saveFile(invoiceid, pdf, 'invoice_i2345.pdf')
  sendDocument(pdf, 'email', 'customer@domain.com', 'Invoice 12345')

Ikke stor forskjell, bortsett fra navngivingen...eller er det ? Metoden sendInvoice trenger referanse til all nødvendig informasjon for å lokalisere den riktige .pdf'en og for å hente kundens epost-adresse, for å nevne noe. I tillegg kan ikke sendInvoice brukes hvis kunden i tillegg ønsker å sende ordrebekreftelser.

Hvorfor generalisere ?

  • Avklaring: I dette eksemplet er det ganske opplagt at det å sende den ferdige fakturaen i f.eks. .pdf-format ikke er forskjellig fra å sende hvilket som helst annet dokument til kunden som informasjon om endrede betingelser, osv.. Å unngå begrepet 'faktura' i denne delen av systemet hjelper til å gjøre dette klart.
  • Utvidbarhet: Når systemeier på et senere stadium ønsker å sende ordrebekreftelser, vil funksjonaliteten for å gjøre dette allerede være tilstede til og med om formålet avviker noe fra hva det opprinnelig var designet for.
  • Gjenbruk: Når utvikleren begynner å arbeide på neste system vil han eller hun allerede ha en fungerende løsning for å sende dokument via epost. Også for helt andre typer system. Koden kan kanskje ikke flyttes over, men løsningskonseptet kan.
  • Arkitekturmessig fleksibilitet: Å unngå at filsendingsfunksjonaliteten trenger kunnskap om en faktura hjelper til å unngå avhengigheter, spesielt toveis. Faktureringsmodulen kan trenge referanser til distribusjonsmodulen, men det forenkler systemet vesentlig om distribusjonsmodulen ikke trenger referanse til faktureringsmodulen. Dette er praktisk om en f.eks. ønsker å flytte distribusjonsmodulen til en annen plattform.
  • Domenekunnskap: Filosofien om å forsøke å dele funksjonalitet inn i ulike aspekt, inkludert det å trekke ut de generelle aspektene, gir deg bedre kunnskap om de virkelige domenespesifikke aspektene. Hva er de domenespesifikke aspektene ved fakturering ? I de fleste tilfeller vil det være det faktum at fakturering er en formell handling i tillegg til å generere et dokument og distribuere det. Regnskapsforskrifter vil vanligvis ikke tillate at en endrer allerede utstedte fakturaer - de må annulleres og erstattes med en ny. Også at det å lage en faktura innebærer å sette inn rader i databasen og generere fakturaen fra disse radene kombinert med data fra kunde- / ordre- / produkttabellene.
    • Aspekter kan dreie seg om dataenheter, teknologier, domeneområder, applikasjonsstruktur og mange andre.
  • Kunnskap: Det kognitive aspektet ved denne filosofien handler om å samle kunnskap - det gjør det mulig for deg å bygge på tidligere erfaring fordi du har maktet å trekke ut enheter og begreper som kan brukes til å løse en annen oppgave selv om det er en annerledes en. Hvis all håndtering av faktura lages med den aktuelle kundespesifiserte fakturaen i tankene, er det en sjanse for at du ikke ville være i stand til å innse at du har erfaring i å lage og distribuere dokumenter i møte med spesifikasjonen til det neste oppdraget ditt.
Generalisering - også for smidig utvikling?

Smidig utviklingsmetodikk erklærer at du ikke burde gjennomutvikle modeller på forhånd, for å unngå overkompleksitet og for å sikre at du faktisk bygger det klienten trenger. Dette kunne lede til en annen tilnærming til faktureringsfunksjonaliteten, men jeg mener fortsatt det er en god idé å gjøre et minimum av generalisering. Utvikling gjennom iterasjoner og omskriving er ikke et argument for å starte med dårlig design som unødvendige avhengigheter og å skrive klasser som absolutt ikke kan gjenbrukes. Ingen drar heller nytte av at utviklerne ikke bygger kunnskap. La oss være pragmatiske og ikke nødvendigvis skrive kode som kan gjenbrukes som den er i neste prosjekt, men legg litt ekstra energi i å forstå bedre hva du konstruerer. Og det er en "dokumentdistribusjonsmodul", ikke en "fakturadistribusjonsmodul".