Arkitekturmönster


Få reda på mer om välstrukturerad resurs- och kostnadsoptimering → Ditt optimeringsansvar

Denna sida ger omfattande mönstervägledning för arkitektoniska problem, inklusive funktionella enheter, separation av problem, tillståndshantering, API-hantering och meddelanden. Dessa mönster formar långsiktig lösningsframgång genom avsiktliga designbeslut om servicegränser, dataåtkomstmönster och komponentansvar.

Mönster

Var man ska letaHur bra ser ut
Apex klasser✅ Serviceklasser följer principen om enskilt ansvar med namn som tydligt anger syftet (AccountService, OrderProcessor, InventoryManager). Varje serviceklass fokuserar på en domän eller verksamhetskapacitet. Metoder inom serviceklasser har enskilda, fokuserade ansvarsområden under 20 rader.
Utlösare✅ Utlösare delegerar till hanterarklasser istället för att innehålla verksamhetslogik direkt. Utlösarhanterarmönster som används konsekvent med tydliga metodnamn efter sammanhang (handleBeforeInsert, handleAfterUpdate). Hanterarklasser organiserar logik efter utlösarhändelse med enskilda ansvarsområden per metod.
Lightning-webbkomponenter✅ Komponenter följer principen om enskilt ansvar med tydliga gränssnitt för konfiguration. Varje LWC fokuserar på ett problem i användargränssnittet (datavisning, användarinmatning, navigering). Komponenter utformade för komposition, inte monolitiska implementeringar.
Servicelager✅ Serviceklasser sammanfattar verksamhetslogik oberoende av startpunkt (utlösare, API, flöde, batch). Samma serviceklass hanterar flera åberopningssammanhang utan dubbletter. Servicelagret separerar verksamhetsregler från problem med presentation och dataåtkomst.
Återanvändbara komponenter✅ Komponenter utformade för återanvändning i flera projekt och team. Konfigurationsdrivet beteende med egna metadatatyper möjliggör beteendeändringar utan koddistribuering. Åberopbara åtgärder visar Apex logik som deklarativa byggstenar som kan användas från flöde och extern orkestrering.

Antimönster

Var man ska letaHur dåligt ser ut
Guds klass⚠️ Undvik att samla på dig överdrivet ansvar i en enda klass. Dela upp stora klasser (>500 rader) i fokuserade klasser med enskilda ansvarsområden. Omorganisera klasser när de hanterar flera orelaterade problem (OrderProcessor ska inte även hantera e-postutskick och rapportering).
Blandade problem⚠️ Undvik att blanda utlösarlogik, verksamhetsregler och dataåtkomst i enskilda klasser. Separera presentationslogik från verksamhetslogik i kontroller. Håll integreringsproblem separerade från kärndomänlogik.
Utlösarlogik i utlösare⚠️ Undvik att bädda in verksamhetslogik direkt i utlösarfiler. Använd aldrig över 300 radutlösare med kapslade villkor. Delegera alltid till hanterarklasser med tydlig metodorganisation efter utlösarsammanhang.

Mönster

Var man ska letaHur bra ser ut
Affärslogik✅ Verksamhetsregler centraliserade i serviceklasser, inte spridda över utlösare, kontroller och batchklasser. Domänklasser sammanfattar postnivåbeteende (validering, standarder, deriverade värden) enhetligt oavsett hur poster kommer in i systemet. Logik återanvänds genom servicelager istället för att dupliceras över kontaktpunkter.
Dataåtkomst✅ Dataåtkomst abstrakt bakom arkiv eller väljarmönsterklasser. SOQL-frågor centraliserade i väljarklasser (AccountSelector, OpportunitySelector) säkerställer enhetliga fältlistor och WHERE-klausuler. Arkivmönstret möjliggör tester med låtsasdatakällor utan att ändra verksamhetslogik.
Gränssnittskontrakt✅ Komponenter kommunicerar genom explicita gränssnitt istället för implementeringsdetaljer. Apex gränssnitt definierar kontrakt mellan lager. Egen metadatakonfiguration definierar beteendegränser. Plattformshändelser tillhandahåller meddelandekontrakt mellan producenter och konsumenter.
Modulgränser✅ Gränsade sammanhang definierar tydliga ägargränser för datamodeller och verksamhetsregler. Varje modul äger sina data, automatisering och verksamhetslogik. Moduler interagerar genom definierade API:n istället för att dela databasobjekt direkt. Dokumentation identifierar tydligt vilket team som äger vilka objekt och tjänster.
Beroendeflöde✅ Beroenden flödar i en riktning (presentation → verksamhet → data). Kärnverksamhetens logik är inte beroende av något externt, vilket möjliggör oberoende utveckling. Infrastrukturproblem (loggning, cachning, externa API) beror på verksamhetslogik genom gränssnitt, inte vice versa.

Antimönster

Var man ska letaHur dåligt ser ut
Logisk duplicering⚠️ Undvik att duplicera verksamhetslogik mellan utlösare, API-slutpunkter och batchklasser. Centralisera i servicelagret och återanvänd över inkörsportarna. När samma verksamhetsregel visas i flera klasser, extrahera till delad tjänst.
Dataåtkomst spridd⚠️ Undvik SOQL-frågor spridda över utlösare, kontroller och batchklasser med inkonsekventa fältlistor och WHERE-klausuler. Centralisera sökfrågor i väljarklasser för att säkerställa enhetliga mönster och aktivera LDV-optimering på en och samma plats.
Verksamhetslogik i utlösare⚠️ Undvik valideringsregler, fältberäkningar och arbetsflödesorkestrering inbäddade direkt i utlösarkoden. Gå till serviceklasser eller domänklasser. Håll utlösare tunna, fokusera endast på att delegera till lämpliga hanterare.
Verksamhetslogik i kontroller⚠️ Undvik komplexa beräkningar, validering eller datamanipulation i Aura/LWC-kontrollmetoder. Kontrollanter ska orkestrera samtal till servicelagret, inte implementera verksamhetsregler direkt.
Cirkulära beroenden⚠️ Undvik paket eller klasser med cirkulära beroenden där A är beroende av B och B är beroende av A. Lös genom att extrahera delade problem till en separat modul, invertera beroenderiktningen eller använda händelsedriven kommunikation för att bryta kopplingen.

Mönster

Var man ska letaHur bra ser ut
Plattformscache (organisationspartition)✅ Ofta besökta referensdata cachade i organisationspartition inklusive egna metadatasökningar, kombinationsrutevärden, konfigurationsinställningar och beräknade resultat av dyra operationer. Standard-TTL konfigurerad baserat på datavolatilitet (timmar för månatliga ändrade referensdata, minuter för ofta uppdaterade konfigurationer). Cachenyckelstrategi förhindrar kollisioner mellan olika datatyper.
Plattformscache (Sessionspartition)✅ Användarspecifika inställningar, beräknade personanpassningsdata och sessionsomfång som lagras i sessionscache. Sessionscache används inte för data som ska delas mellan användare. Strategin för ogiltighetscache hanterar uppdateringar av användarpreferenser korrekt.
Lightning Data Service✅ LDS tillhandahåller automatisk cachning av klientsida för Lightning. Standard CRUD-operationer använder LDS istället för egna Apex kontroller. LDS eliminerar överflödiga serverturer och ger optimistiska uppdateringar av användargränssnittet. Komponenter använder delat LDS-cache över sidan.
Egna metadatatyper✅ Konfiguration och beteenderegler som lagras i egna metadatatyper snarare än hårdkodade i klasser. Egna metadata som kan distribueras mellan miljöer via ändringsanvisningar eller källdriven utveckling. Ändringar av egna metadata kräver inte fullständig distributionscykel. Cacha egna metadatafrågor i plattformscache för prestanda.

Antimönster

Var man ska letaHur dåligt ser ut
Sökfråga i Loop⚠️ Undvik att köra SOQL inom iterationsloopar. Fråga alla poster som behövs i ett enskilt SOQL-uttryck utanför loopar. Organisera resultaten i Kartor efter överordnat ID för sökning under upprepningen. Detta är det enskilt vanligaste Salesforce-antimönstret.
Repetitiva sökfrågor⚠️ Undvik att fråga samma egna metadata, egna inställningar eller referensdata flera gånger per transaktion. Fråga en gång, cache i plattformscache eller statisk variabel för transaktion, återanvänd över hela transaktionen.
Strategi för cache saknas⚠️ Undvik att upprepat fråga ofta besökta referensdata utan cachning. Implementera plattformscache för egna metadata, konfiguration och beräknade resultat. Definiera lämplig TTL baserat på datavolatilitet.
Cache utan ogiltighet⚠️ Undvik att cacha data utan att överväga en ogiltighetsstrategi. Definiera TTL för cache lämplig för att uppdatera frekvens. Implementera manuell cacherensning när källdata ändras om endast TTL är otillräckligt.
Ohanterat sessionsläge⚠️ Undvik att anta att sessionsstatus kvarstår över sidnavigeringar utan verifiering. Lightning ska hantera statusuppdatering vid sidinläsning. Använd Lightning Data Service för automatisk synkronisering av status.

Mönster

Var man ska letaHur bra ser ut
Planering av lösningsarkitektur✅ Arkitekturplanering inträffar innan betydande bygginvesteringar, inklusive kravanalys (funktionell och icke-funktionell), analys av styrande gränser för förväntade datavolymer, mönsterval som är lämpliga för krav och komponentdesign som definierar huvudkomponenter och gränssnitt.
Val av designmönster✅ Beprövade Salesforce-designmönster tillämpas konsekvent: Servicelagermönster för återanvändning av affärslogik, Arkiv-/väljarmönster för abstraktion av dataåtkomst, Strategimönster för utbytbara algoritmer, Domänmönster för beteende på postnivå, Utlösarhanterarmönster för enhetlig organisering av utlösare.
Poster för arkitekturbeslut✅ Betydande arkitektoniska beslut dokumenterade i ADR som lagras i versionskontroll. Alternativ tvistlösning samlar in sammanhang (affärsdrivkrafter, tekniska begränsningar), beslut (vad som valts), alternativ som övervägts (varför andra avvisat) och konsekvenser (avvägningar, teknisk skuld, utlösare för återbesök).
Bygg vs köputvärdering✅ AppExchange utvärdering föregår egna utvecklingsbeslut med hjälp av total ägandekostnadsanalys. Utvärderingskriterier inkluderar strategiskt värde (konkurrenskraftig differentierare vs råvara), jämförelse av totalkostnad (byggarbete, underhåll, uppgraderingskostnader), integreringskomplexitet och exitkostnad om lösningen visar sig vara otillräcklig.
Analys av guvernörsgräns✅ Arkitektonisk planering identifierar vilka styrande gränser mest begränsa design med tanke på förväntade datavolymer och transaktionsmönster. Transaktioner utformade för att konsumera mindre än 80 % av en enskild styrande gräns under rusningstid. Marginal byggd för tillväxt, framtida funktioner och oväntade användningsmönster.
Riskbedömning✅ Tekniska risker identifierade för arkitektoniska metoder som flyttar plattformsgränser. Begränsningsstrategier som definieras för varje betydande risk. Prototyparbete eller arbete med konceptbevis validerar antaganden för tekniska högriskmetoder innan ett fullständigt byggåtagande.

Antimönster

Var man ska letaHur dåligt ser ut
Ingen planering⚠️ Undvik att börja bygga utan att analysera datavolymer, konsekvenser för styrande begränsningar eller mönsterval. Workshopen för arkitekturplanering ska identifiera viktiga begränsningar, välja mönster och validera mot styrande gränser innan byggandet börjar.
Odokumenterade beslut⚠️ Undvik arkitektoniska beslut som fattas i möten utan att samla in sammanhang, logik, alternativ och konsekvenser. Använd Poster för arkitekturbeslut som lagras i versionshantering för att bevara beslutssammanhang för framtida teammedlemmar.
Ingen byggnad vs köpanalys⚠️ Undvik att bygga egna lösningar utan AppExchange utvärdering. Utvärdera de bästa 3-5 relevanta paketen innan egen utveckling. Jämför TCO inklusive implementeringsinsatser, underhålls-, uppgraderingskostnader och avslutskostnader.
Underteknik⚠️ Undvik att endast utforma för aktuella datavolymer utan tillväxtprognos. Projektera datatillväxt under 2-3 år. Utforma sökfrågemönster med selektivitet validerad mot 5-10x aktuella volymer. Bygg arkitektonisk marginal för tillväxt.

Mönster

Var man ska letaHur bra ser ut
Andra generationens hanterade paket (2GP)✅ 2GP används för nya hanterade paket som kräver namnutrymmesisolering, AppExchange distribution och IP-skydd. Källdrivet utvecklingsflöde med modulär programutveckling. Paketberoenden som hanteras uttryckligen. Versioner som släppts med semantisk versionshantering.
Olåsta paket✅ Olåsta paket som används för interna företagsprogram som kräver modularitet utan begränsningar av namnutrymme. Oberoende distribuering av paket utan organisationsberoende artefakter. Paketberoenden spårade för korrekt distributionsordning. Versionshanteringsstrategi definierad för interna paket.
Modulgränser✅ Tydliga ägargränser definierade för varje paket. Varje paket äger sin datamodell, sina verksamhetsregler och sin automatisering. Paket interagerar genom definierade gränssnitt istället för direkt objektåtkomst. Dokumentation identifierar paketägande och kontrakt mellan paket.