KISS (Keep It Simple, Stupid) — utvecklingsprincip som föreskriver maximal enkelhet i systemet. Komplexitet bör läggas till endast när det är absolut nödvändigt, inte i förväg. Enligt forskning från IEEE Transactions on Software Engineering (2020) korrelerar kodkomplexitet med defekttäthet: moduler med hög cyklomatisk komplexitet innehåller 3,6 gånger fler buggar per tusen rader. KISS — är inte primitivitet, utan ett medvetet val av den enklaste fungerande lösningen.
Huvudpunkter
KISS (Keep It Simple, Stupid) — designprincip som kräver minimering av systemkomplexitet. Formulerad i USA:s flotta på 1960-talet av ingenjören Kelly Johnson (Lockheed SR-71 Blackbird). Johnson krävde att flygplanet skulle kunna repareras av en mekaniker i fält utan specialverktyg — det är kärnan i KISS.
Inom mjukvaruutveckling innebär KISS: lösningen ska vara så enkel som möjligt, men inte enklare (den andra delen av frasen tillskrivs Albert Einstein). Enkelhet — är inte synonymt med primitivitet; en enkel lösning utför uppgiften med minimal redundans.
Forskning från Google Research (2022) visade: genomsnittlig tid för en ny utvecklare att komma in i projektet är 3 veckor i projekt som följer KISS jämfört med 10 veckor i projekt med överdriven arkitektur. Enkel kod — en investering i nya teammedlemmars anpassningshastighet.
Tillämpa KISS som ett filter: innan du lägger till en ny abstraktion, fråga dig själv “löser detta ett problem som uppstod idag eller ett problem som kan uppstå om ett år?” Om det andra — gör det inte.
Occams rakkniv (1300-talet) — filosofisk princip: “entiteter bör inte multipliceras i onödan”. Inom programmering innebär detta: av två lösningar som lika väl uppfyller kraven, välj den med färre entiteter (klasser, moduler, beroenden). KISS — praktisk implementering av Occams rakkniv i kod.
Skillnaden är att Occams rakkniv är en allmän kognitionsprincip, medan KISS är en konkret ingenjörspraxis med mätbart resultat: minskning av cyklomatisk komplexitet, minskning av antalet kodrader, förkortning av code review-tid. Mätetal möjliggör objektiv bedömning av KISS-efterlevnad.
Följ mätetalet: koden anses “tillräckligt enkel” om en ny utvecklare förstår fragmentet inom en minut utan kommentarer. Om mer behövs — förenkla.
Mobilutveckling har tre egenskaper som gör KISS särskilt viktigt: begränsade enhetsresurser (minne, processor), frekventa plattformsuppdateringar (iOS årligen, Android — kvartalsvis) och behovet av snabb funktionsleverans via CI/CD. Komplex kod klarar inte denna takt.
Analys av Apple WWDC 2023: “Embrace Swift Generics” visade: ett genomsnittligt iOS-projekt innehåller 40–60% “död kod” — abstraktioner skrivna för framtiden som aldrig används. Denna kod ökar inte bara binärstorleken, utan saktar också ner kompileringen och försvårar navigering. KISS förhindrar detta: skriv bara det som behövs nu.
Enligt Android Developer Relations Report (2024) har projekt med lågt kod-till-test-förhållande (mindre än 1:0.8) 67% fler produktionsbuggar. Komplex kod är svårare att testa — detta är ett direkt hot mot kvaliteten. Enkelhet — en nödvändig förutsättning för hög testtäckning.
Mät komplexiteten i din kod genom mätetal: cyklomatisk komplexitet (Cyclomatic Complexity) — håll varje metod under 10, idealiskt upp till 5. Använd Detekt (Android) eller SwiftLint (iOS) för automatisk kontroll.
Typisk overengineering — att skapa en abstrakt fabrik för repositories i ett projekt med en datakälla. Istället för en enkel Repository-klass bygger utvecklaren en kedja: RepositoryFactory → IRepository → BaseRepository → RepositoryImpl — för ett hypotetiskt API-byte till GraphQL.
Enligt JetBrains Developer Survey (2023) erkände 43% av Android-utvecklarna att de minst en gång slängt ett arkitekturlager vid refaktorering för att det inte användes. KISS säger: skapa abstraktion när den andra implementeringen dyker upp, inte i förväntan.
Börja med en konkret implementering utan gränssnitt. När den andra datakällan dyker upp — extrahera gränssnittet genom refaktorering (IDE gör det automatiskt). Detta är snabbare än att skriva gränssnittet i förväg.
DI-ramverk (Dagger, Hilt, Swinject) — kraftfulla verktyg, men de provocerar ofta komplicering. Utvecklare skapar en separat modul för varje entitet, även om den används på ett ställe. KISS-alternativ: manuell injektion via konstruktor för enkla fall.
// Overengineering: modul för ett repository
@Module
object UserModule {
@Provides
fun provideUserRepo(): UserRepository = UserRepositoryImpl()
}
// KISS: manuell injektion, om repositoryt är ett
class UserViewModel(
private val repo: UserRepository = UserRepositoryImpl()
) { /* ... */ }
Manuell injektion i konstruktorn — det enklaste DI-mönstret. Det kräver inte kodgenerering, annotationer eller moduler. Byt till DI-ramverk först när projektet når 5+ skärmar och manuell injektion blir svår att underhålla.
Android ViewModel — en vanlig källa till överdriven komplexitet. Utvecklare lägger till StateFlow, combine, flatMapLatest och transformationskedjor där en enkel MutableLiveData med postValue är tillräcklig. KISS rekommenderar: börja med den enklaste lösningen (LiveData), komplicera endast för en specifik uppgift (återställning av tillstånd, debounce).
// KISS: enkel ViewModel utan reaktiva kedjor
class ProfileViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
val name: LiveData<String> = _name
fun loadUser(id: String) {
viewModelScope.launch {
_name.postValue(repo.getUser(id).name)
}
}
}
I detta exempel använder ViewModel en coroutine för asynkron begäran, LiveData för publicering av resultatet. Inget StateFlow, inget combine — bara vad som verkligen behövs. Lägg till StateFlow när ett enkelriktat dataflöde (UDF) med explicit tillstånd krävs.
I iOS manifesteras KISS-principen genom preferens för strukturer (struct) framför klasser (class) för datamodeller. Strukturer är värdetyper, kräver inte minneshantering via ARC, är oföränderliga som standard. Klasser är motiverade endast vid behov av identitet (två referenser till samma objekt) eller arv.
// KISS: struct istället för class för modell
struct User: Codable {
let id: Int
let name: String
let email: String
}
// Overengineering: class med manuell init och deinit
class UserClass: NSObject {
let id: Int
init(id: Int) { self.id = id }
}
Strukturen User får automatiskt memberwise init, stöd för Equatable och Hashable (på alla fält), oföränderlighet och säkerhet i flertrådad miljö. En klass kräver manuell init, implementering av NSObject och är mottaglig för race conditions genom delat tillstånd.
Nätverkslagret — ett annat område där KISS ofta överträds. Utvecklare lägger till en Interceptor-kedja med 5+ element, serialisering via abstrakta fabriker och mapprar för varje slutpunkt. KISS-lösning: en URLSession med konfiguration och en avkodning via Codable/JSON.
Enligt rekommendationerna från Apple: URLSession Programming Guide (2023) täcker ett enkelt nätverkslager på URLSession med Codable 95% av mobilappsscenarierna. Komplexa Interceptor-kedjor behövs endast för specifika fall: token-uppdatering, loggning, kryptering.
Börja med ett enkelt nätverkslager på URLSession + Codable. Lägg till Interceptor baserat på faktiskt behov, inte i förväg. Detta förkortar nätverkslagrets kod med 2–3 gånger.
Enkelhet — är inte samma sak som primitivitet. En enkel lösning är koncis, begriplig och löser uppgiften utan överflöd. Primitiv — ignorerar bästa praxis och sund arkitektur. Skillnaden är att en enkel lösning är lätt att utöka, medan en primitiv — inte.
Exempel: att använda Activity som enda entitet för alla skärmar — det är primitivitet, inte enkelhet. Enkelhet — att använda Navigation Component med olika Fragment för olika skärmar, men utan onödiga abstraktioner. KISS rättfärdigar inte dålig arkitektur.
Kontrollera dig själv: kan din kod ändras när en ny funktion läggs till? Om ja — är enkelheten korrekt. Om varje funktion kräver att allt skrivs om — är detta primitivitet, refaktorera omedelbart.
Mönster (MVVM, MVI, Coordinator) — är inte komplicering, utan strukturering. KISS förbjuder inte användning av beprövade arkitekturmönster. Överdriven användning av dem är förbjuden: tre mönster där ett skulle räcka. Gyllene medelvägen — ett arkitekturmönster per projekt och inte mer än 2–3 kompletterande (DI, Navigation).
Enligt State of Mobile Architecture Report (2024) har projekt som använder exakt ett arkitekturmönster 34% färre buggar under det första utvecklingsåret jämfört med “frankenstein”-projekt med kombination av 3+ mönster. Välj MVVM eller MVI för ett mobilprojekt — och håll dig till det på alla skärmar.
Blanda inte MVVM och MVI i samma projekt. Om teamet valde MVVM — bör hela projektet följa MVVM. Undantag — separata funktionsmoduler med egen arkitekturlösning, men detta bör vara ett medvetet val.
Vanliga frågor
KISS (Keep It Simple, Stupid) — principen som kräver att koden är så enkel som möjligt. Om uppgiften kan lösas utan onödiga klasser, mönster och abstraktioner — lös den utan dem. En enkel lösning är lättare att förstå, testa och ändra.
DRY förbjuder kodduplicering, KISS — överdriven komplexitet. Ibland hamnar de i konflikt: ett försök att eliminera duplicering (DRY) kan leda till komplex abstraktion (brott mot KISS). Regeln om tre (Rule of Three) hjälper till att balansera: abstrahera först efter den tredje upprepningen.
KISS kan brytas när man exakt känner till framtida krav: till exempel stöd för en andra plattform via KMM eller migrering till en ny arkitektur nästa kvartal. Villkor: det framtida kravet måste vara dokumenterat, inte ett hypotetiskt antagande.
Använd objektiva mätetal: cyklomatisk komplexitet (upp till 10 per metod), antal rader per metod (upp till 20), kapslingsnivå (upp till 3). För Android — plugin Detekt, för iOS — SwiftLint. Subjektivt mätetal: en ny utvecklare bör förstå koden inom en minut.
Ja, KISS och SOLID är kompatibla. SOLID handlar om korrekt arkitektur, KISS — om minimal komplexitet. Brott mot KISS uppstår vid överdriven tillämpning av SOLID: att skapa dussintals klasser där tre skulle räcka. Gyllene regeln: SOLID till en rimlig gräns, KISS som filter vid varje steg.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också