Vad skulle du säga är de främsta programmeringsriktlinjerna i god programmering. Det finns ju en del men vad skulle du säga var de som du skulle vilja att andra börja följa mer. De områden som jag spontant kan komma på och som jag tror många kan bli bättre på är: Jag saknar återanvändning, dokumentation och designpatterns i din lista, ta bort nr. 5, 4 och 3 och ersätt de med mina så täcker du allt ditt och lite till.. Går inte återanvändning även in på punkt 1 och 2? Jo till en viss del går det in på punkt ett och två. Med dokumentation menar jag främst funktionsdokumentering, den övergripande är inte lika intressant som att få reda på vilket ansvar en viss metod / funktion har. På vilket sätt funktionsdokumenterar man enligt dig? För det finns lite olika sätt att göra detta på. Antar att han syftar på t.ex. visual studios Jag ser kanske en eller två funktioner på ett år där jag känner att dokumentation hade varit lämpligt. Jo jag syftar på summary-taggarna och liknande metoder. I stort håller jag med Niklas men bör även tillägga man bör ha som regel att berätta vilka funktioner man gjort testfall för. Dock så bör man komplettera med mer dokumentation, ofta är ett namn självklart när man bygger lösningen, lika ofta är det kryptiskt för andra... Jag kan inte hålla med dig niklas. Vet inte om du programmerat i php men där blir det ofta väldigt krångligt eftersom man skickar flerdimensionella arrayer hit och dit och det händer ofta att man inte vet vilket format det ska vara på en input-array eller det som returneras. Jag kan tänka mig att sträcka mig till att kommentera luriga metoder men inte mer än så. Skulle man kommentera varje metod så skulle det vara en slöseri med tid, pengar och kraft. Skulle man tex ha en metod som heter GetCustomerByID så beskriver den på ett bra sätt vad metoden gör. I dessa fall skulle jag se det som överdokumentation att lägga till en summary-tag. <b>>Vet inte om du programmerat i php men där blir det ofta väldigt krångligt eftersom man skickar flerdimensionella arrayer hit och dit och det händer ofta att man inte vet vilket format det ska vara på en input-array eller det som returneras.</b> Jag kunde tyvärr inte begränsa mig till fem när jag började skriva :-) Jag håller inte med, i de flesta fall som man känner att man behöver dokumentera så har man skrivit otydlig kod enligt mig. Har man bra metodnamn, där metoderna är på max 4-7 rader så beskriver metodnamnen vad koden gör då behövs ingen dokumentation som behöver bli underhållen. Jag bryter inte enbart ut kod i nya metoder för att återanvända dom utan även för kodförståelse, <b>Att använda Summary's är jättebra om man skriver ramverk som en tredjepart skall använda sig av eller om det i undantagsfall inte gått att beskriva vad metoden gör med namnet i det context som klassnamnet är.</b> Som du säger återanvänds koden i sex andra mjukvaror låter som en typ av tredjepartskomponenter för mig. <b>Det kvittar om det driftas hos 9.000 kunder eller hur länge det har underhållits, metodnamnen blir inte mer intetsägande för det.</b> Hur många år av erfarenhet har du att jobba enligt Lean och Agile? :) Olika agila metoder har jag jobbat med sedan 1998, lean har jag lite dålig koll på öht. Inget av det jag säger motsägs dock utav någon av de olika agila metoderna jag jobbat med. Jag vill dock mena på att agila metoder är bättre för mindre projekt och som avstamp för lite större projekt de är inte så bra för underhåll och vidareutveckling av stora mjukvaror med hög komplexibilitet på grund av det täta samarbete som krävs inom projektgrupperna då man i normal värld (för mig) har en tre - fyra projekt igång hela tiden. För mig handlar Lean och Agile mycket om att ta hänsyn till komplexitet och försöka minimera så mycket onödig komplexitet som möjligt för att det dels påverkar kvalitén på det man levererar men också produktiviteten, dvs ju högre komplexitet desto lägre produktivitet och fler fel m.m. Vilka metoder är bättre att jobba med när det kommer till "vidareutveckling av stora mjukvaror med hög komplexitet"? Jag och många med mig föredrar metoder med lite mer formell styrning när det handlar om vidareutveckling av lite större projekt, rup och liknande är aningen overkill men de behöver inte vara helt fel, huvudanledningen till detta är att agila metoder bjuder in till stickspår från specifikationen och att de också äter massor av resurser om man är med i flera parallella projekt utan att ta hänsyn till de andra projekten. Jag personligen gillar att utveckla med scrum men inte i de lägen där man har så mycket som fyra till tio parallella projekt, där föredrar jag fishbone (ett derivat av rup) eller rup så att allt som äter tid tydligt kan påverka tidsplanerna för alla inblandade utan att man behöver stämma av hela tiden. Jag tror jag förstår men Lean och Agile är inte mot formell styrning. Om en form av process skapar ett värde för kunden då är det något man bör göra. Samma gäller med dokumentation. Om det finns ett värde att tex kommentera en GetCustomerByID-metod då bör man göra det. MEN om det finns andra bättre sätt att skapa samma result som en specifik process, dokumentation eller något liknande då bör man välja det sättet framför det som har mindre värde. Det handlar mycket om att hitta en optimal avkastning för de pengar som kunden investerar. Det bästa vore om kundens pengar vore obegränsade men eftersom de aldrig är det då blir viktigt att välja och prioritera att göra rätt saker. För ju mer onödigt och ineffektivt arbete man gör desto mindre viktigt arbete hinner man med. Vilket i sin tur påverkar hur systemet, förvaltningen m.m. blir i slutändan.Topp fem programmeringsriktlinjer?
1. Inkapsling
2. Överlagring
3. Bryta ned långa metoder till mindre
4. Reducera logik i GUI:t (code behind) och få ned det i domänlagret istället
5. Eftersträva enkla API:er med få inparametrar till metoder Sv: Topp fem programmeringsriktlinjer?
Sv:Topp fem programmeringsriktlinjer?
När du säger dokumentation vad syftar du på då? Jag kan hålla med om att dokumentation kan vara bristfällig i vissa fall men det kan också vara klumpig i andra fall och inaktuell. Jag tror mycket på lättviktig dokumentation. Det handlar väl lite grovt om att inte underdokumentera eller överdokumentera.Sv: Topp fem programmeringsriktlinjer?
Sv:Topp fem programmeringsriktlinjer?
Sv: Topp fem programmeringsriktlinjer?
///<summary></summary> eller zends /** @param @return och liknande. Och kan bara hålla med där, det hälper otroligt mycket, speciellt i svagt typade (tror det kallas så?) språk som t.ex. PHP där du inte ens vet vad det är för typ på parametrar/returvärde annars.Sv:Topp fem programmeringsriktlinjer?
En funktion ska för mig ha följande egenskaper:
1. En enda uppgift
2. Beskriven så mycket det går "kodmässigt". (Dåligt exempel: döp inte funktioner till "_private" på slutet - gör dem privata istället)
3. Namn (inkl inparametrar och deras namn) som återspeglar uppgiften, och som även i viss mån täcker annan information om funktionen som inte framgår.
Om det är mycket sånt så borde det förmodligen synas i inparametrar istället för i namnet.
All information som krävs för att använda funktionen bör vara täckt här. Den information som återstår är i 95% av fallen lika lätt att förstå genom att titta på funktionen, som att läsa det i text.
Det lilla som är kvar är något nydanande algoritmer, hårt optimerade grejer, etc. och det är fan inte ofta man ser det eller tvingas göra det.Sv: Topp fem programmeringsriktlinjer?
Sv: Topp fem programmeringsriktlinjer?
Tänk också på att man inte alltid har tillgång att läsa funktionen som anropas, då är det ännu viktigare att den är bra dokumenterad.
Kan ju tillägga igen att jag inte känner det här behovet lika mycket i .NET där man vet vad som ska in och vad som kommer ut utan att dokumentera.Sv:Topp fem programmeringsriktlinjer?
Sv:Topp fem programmeringsriktlinjer?
Jobbat väldigt lite i php, men det finns väl klasser?
Vad är anledningen till att man inte använder dem isf?
<b>>Tänk också på att man inte alltid har tillgång att läsa funktionen som anropas, då är det ännu viktigare att den är bra dokumenterad.</b>
Om man inte har tillgång till en funktions implementation så är den ju rimligtvis antingen av "library"-typ, och då är mina punkt 1 och 2 ännu viktigare, eller av typ "annan leverantör som vill hålla sin kod privat", och samma gäller där.
Sen - visst. Ju färre språkkonstruktioner som finns/används, desto mer måste man säga i fritext. Språken börjar ju komma igång med det nu. (Sen är det en bit kvar till lisp, förstås, men det är en annan fråga.)Sv: Topp fem programmeringsriktlinjer?
1. Refaktorisera kontinuerligt
Yrkesstoltheten verkar det vara lite si och så med i vårt yrke, eller rättare sagt yttrar den sig ofta på ett annat sätt än vad jag skulle önska, och det verkar inte vara så vanligt att utvecklare lever upp till pragmatic programmer -principen "Don’t Live with Broken Windows".
Med tanke på hur all kod brukar se ut (som jag har sett under alla mina yrkesverksamma år) så tror jag inte att det är särskilt många som brukar snygga till koden när den är (funktionellt) "klar" utan snarare skyndar man snarast möjligt vidare till nästa uppgift i stället för att refaktorisera och slippa lämna efter sig något som man inte alls kan vara stolt över.
Istället borde man ägna en stund till att läsa igenom koden ordentligt för att se om den ser välustrukturerad ut, med bra namn på alla abstraktioner och metoder och parametrar, och om metoderna verkligen ligger placerade i rätt klass/interface eller kanske borde flyttas till en annan typ, och om det finns duplicerad kod som kan återanvändas med lite mer refaktorisering o.s.v.
Dock kan yttre omständigheter ibland göra det omöjligt att skapa kod som man kan känna sig stolt över, t.ex. kan man tvingas anpassa sig till en applikations befintliga grundarkitektur som skickar omkring hashtabeller överallt (istället för egendefinieade domänklasser) i procedurorienterad kod med eget persisteringsramverk för hashtabellerna, men man får ändå försöka göra det bästa av situationen och t.ex. åtminstone refaktorisera namnen så att de blir så beskrivande som möjligt.
Jag håller f.ö. med Michael Feathers, som citeras i boken Clean Code angående hur "ren kod" kan definieras: "Clean code always looks like it was written by someone who cares."
2. Skriv testkod (och skriv den helst innan den verkliga koden skrivs)
Om man tillämpar TDD/BDD så producerar man inte bara tester som kan användas för regressiontestas (vilket underlättar för att våga refaktorisera) utan det är också ett bra design-hjälpmedel att skriva testerna först, eftersom man tvingar sig tänka efter exakt hur klientkoden borde se ut så ökar man chansen till att den faktisk blir tydligt läsbar och innehåller förhållandevis få beroenden till andra samarbetande objekt.
Testkoden är exekverbar exempelkod som således även fyller ett dokumentationssyfte och visar hur en metod kan användas och vad den förväntade effekten är.
3. Tänk alltid på att koden inte bara skall vara exekverbar för en dator, utan den skall vara läsbar för en människa också
Semantik är oerhört viktigt (dsv man skall använda "intention-revealing names") eftersom koden läses betydligt oftare än den skrivs, och för att kunna skriva ny kod som utökar den befintliga så måste den befintliga koden vara begriplig, och det är väldigt störande för läsbarheten med ogenomtänkta eller för korta/kryptiska/diffusa namn på olika saker.
Det är i synnerhet extremt viktigt för alla publikt synliga namn, dvs interface/klasser och publika metoder och metodparametrar.
Använd inte super-generella typer såsom "Object" eller "HashTable" i publika metod-signaturer. Det är inte ett långsiktigt bra sätt att skriva återanvändbar kod, och det är inte särskilt roligt att jobba med en applikation där egendefinierade domänklasser saknas utan i stället skickas omkring som hashtabeller som persisteras av ett eget ramverk och med procedurell kod som applicerar logik överallt på hashtabellerna.
Reflektionskod bör inte användas i vanlig applikationskod (men användning av reflektion är mycket befogad vid implementationen av vissa generella typer av ramverk såsom persisteringsramverk, eller kan vara det för att t.ex. generera kod).
Det är enkelt för dig att skriva reflektionskod, men det kommer sannolikt att medföra att andra utvecklare kommer känna sig tvingade att slösa tid på att debugga den "obfuscated" källkod som du producerar genom din reflektion. I en välskriven metod så bör du helst kunna läsa koden med alla dess metodanrop utan att behöva hoppa in i respektive metod för att läsa dess kod, men det är förstås ett mycket stort snäpp värre om du då hamnar i en metod som drar igång ett refektionsanrop med lite klass/metodnamn och parametrar som hämtas från en hashtabell eller hämtas ut från en databas.
Det är milt sagt störande att behöva försöka debugga igång ett användningsfall för att kunna förstå och skaffa sig en överblick över anropskedjan.
Sedan är det förstås inte heller refaktoriseringsvänligt med en applikation som man vet använder sig av reflektion och man inte får mycket hjälp av kompilatorn för att uptäcka fel.
(såvida man inte råkar vara så ovanligt lycklig lottad som att man har tillgång till en omfattande svit med regressionstester som kan fånga upp problem med t.ex. ändrade namn på saker...)
4. Återanvänd så mycket som möjligt (både när det gäller konkret fysisk teknik såsom infrastruktur/ramverk/klassbibliotek, samt när det gäller ideer/applikationsstuktur o.s.v. t.ex. arkitekturmönster och designmönster)
Fokusera på det som är specifikt för din applikation, och var återhållsam med kreativiteten (dvs att försöka återuppfinna hjulet igen) och ställ dig hela tiden frågan om det är sannolikt att många andra har ställts inför ett liknande problem, och om det kan finnas någon komponent som du kan återanvända i stället för att slösa tid på att själv skriva samma sak.
Undvik att ha så höga tankar om dig själv, och resonera som att "det är bäst att göra det själv så man vet att det fungerar".
Det finns faktiskt väldigt många open source komponenter av väldigt hög kvalitet, och det är ofta slöseri på tid att försöka skapa något eget av lika hög kvalitet, och i synnerhet är det väldigt onödigt att skriva/förvalta ett eget persisteringsramverk (om det förstås inte är själva ramverket som är din applikation, t.ex. om du är en av Hibernate-utvecklarna...)
För att förvissa sig om att en potentiellt återanvändbar komponent faktiskt erbjuder den funktionalitet som du är ute efter, så kan du definiera ditt eget interface som din klientkod behöver (dvs tillämpa "Dependency Inversion principle") med ett slags Adapter-interface som du sedan skriver testkod för (ett s.k. "Learning Test"). Sedan implementerar du din Adapter så att testerna fungerar som det ska, genom en enkel impementation som använder sig av en tredjepartskomponent som Adaptee.
Det är inte heller bra att hitta på egna arkitekturer och kodstrukturer (potentiella "mönster", men observera att "mönster" per definition inte kan hittas på, utan de skall identifieras från flera olika applikationer) som ingen annan kommer att känna igen, utan det är bättre att läsa på ordentligt, och återanvända beprövade principer och mönster, t.ex. böcker som "Patterns of Enterprise Application Architecture", "Domain-Driven Design", samt förstås "Design patterns" boken.
Det underlättar kommuikationen/dokumentationen om man kan referera till etablerade koncept, så att andra utvecklare snabbt kan känna igen sig, t.ex. kan man i dokumentationen för en klass påpeka att den fungerar som en Director i designmönstret Builder, så behöver man ingen lång utläggning (givetvis under förutsättning att läsaren känner till designmönster). Man skall naturligtvis också återanvända egenproducerad kod på ett snyggt sätt utan kodduplicering (copy/paste-programmering) men det är (eller åtminstone borde vara) egentligen så självklart att jag nu nästan höll på att glömma att nämna det under denna punkt om återanvändning.
5. Motverka spaghetti/ravioli-kod genom att tänka på inkapslingen
I den mesta koden jag har sett (i böckers kodexempel eller verklig kod) så är det vanligt att "fält" (eller medlemsvariabler/attribut, med en terminologi som varierar med programmeringsspråk) visserligen definieras som private, med samtidigt exponeras via publika getters som returnerar direkt åtkomst till det privata fältet, som oftast kan förändras, dvs är mutable.
När man inte kontinuerligt tänker på inkapsling, så leder det inte sällan till följande typ av ravioli-kod, där nästan vad som helst kan ändras nästan var som helst:
a.getB().getC().getD().getE().setF(someValueBeingSetToMutablePrivateFieldOf_E_byDistantStranger);
Det är dock långt ifrån alltid koden är skriven på ovanstående sätt med en så tydlig "Law of Demeter -violation" (även känd som "Don't talk to strangers", som ingår i GRASP - "Protected Variation") utan de olika returvärdena är ofta mellanlagrade i variabler, med diverse kod emellan i stället för att skriva alla punkter på en och samma kodrad som ovan.
Man kan försöka kapsla in koden bättre genom att bl.a. undvika att exponera getters och i stället försöka tillämpa "Tell, Don't Ask"-principen, och man kan också exponera ett mutable objekt via en getter som returnerar det som ett immutable interface. En annan variant är att retunera en kopia av det privata fältet, men det sistnämnda är inte optimalt eftersom det är otydligt och kan uppstå missförstånd angående vad som ändras, t.ex. om klientkoden kan göra följande anrop: "a.getB().setC(someValue)" så är det sannolikt att den som läser koden då tror att man faktiskt modifierade ett fält C som aggregeras av B snarare än att man modifierade en kopia.
6. Försök placera metoderna på lämplig klass
Man bör tillämpa tillämpa de objektorienterade GRASP-principerna, såsom "Low Coupling" och "High Cohesion", men det vanligaste misstaget tror jag är att inte tänka på att beakta "Information Expert", utan skriva en massa "getters" på dumma databärande klasser som man sedan applicerar procedurell logik på från en annan "Service-klass", i stället för att försöka placera metoder i den klass som innehåller det mesta av datat, och då kanske man kan undvika att exponera publika getters i onödan (googla även på GetterEradicator och "anemic domain model").
Genom att inte försöka placera metoden där den hör hemma, dvs i klassen tillsammans med det mesta av datat, så ökar risken för duplicering, dvs att en annan utvecklare inte kommer att hitta till din procedurella kod som är utspriden på andra procedurorienterade klasser, och alltså skriver om något liknande som redan finns, istället för att återanvända (eventuellt efter viss refaktorisering).
Om man vill använda en metod som man inte vet om den redan finns eller inte, så är det alltså naturligt att börja leta i den klass som innehåller datat, men om man inte hittar den önskade koden där så är det inte alltid så lätt att söka igenom ett system med tusentals klasser. Särskilt svårt är det förstås att hitta eventuellt befintlig kod ifall den har implementerats med att exponera några av fälten som primitiva typer (t.ex. heltal) och som skickas vidare till en utility-metod som tar emot några sådana heltal. Man kan då nämligen få väldigt många träffar i ett stort system om man försöker tillämpa IDE'ns "Find references" för att försöka hitta en kodsnutt som kanske skulle kunna finnas någonstans.
Detta är f.ö. också en anledning till att använda gendefinierade typer i stället för att ofta återanvända den befintiliga klassen String för enkla koncept som i princip bara består av en sträng.
Det blir alltså lättare att hitta metoderna som kan återanvändas för att hantera ditt koncept om den är egen datatyp snarare än att söka igenom hela systemet efter procedurella metoder som tar en sträng som parameter.
7. Lär dig, och försök tillämpa Liskovs substitutionsprincip
Det räcker inte med att bara tänka på hur basklasser/subklasser förhåller sig till varandra konceptuellt (dvs med en "is-a-relation") utan man skall tänka på beteendet i metoderna och att klientkoden, dvs koden som använder sig av en referens till en bastyp, skall använda den på ett transparent sätt dvs utan att ta hänsyn till vilken specifik konkret subtyp som den refererar till.
Ett horribelt exempel som jag har stött på, och som jag tyvärr inte tror är särskilt ovanligt, är en metod-parameter som är typad som "Object" och som skickas vidare i många publika metod-signaturer, för att slutligen inuti en metod blir typkontrollerad och bli downcastad till antingen en String eller en Integer eller ett egendefinierat objekt, alternativt förstås kastar ett exception.
Detta hemska exempel är förstås applicerbart även för punkt 3 ovan, angående att koden ska vara läsbar, med "intention-revealing interfaces".
Det här sättet att implementera "generell" kod är ofta baserad på okunskap om designmönster såsom Command och Adapter, d.v.s. det går oftast att skapa typade metodsignaturer utan att behöva använda "Object" och t.ex. använda reflektionsanrop. Jag har själv sett flera gånger i olika applikationer att ett "Object" läggs in i ett slags "worker thread" för att senare exekvera, kanske vid en viss tidpunkt.
Ett problem här är att metodsignaturen ljuger då den kommunicerar att den kan hantera vilket "Object" som helst, trots att den faktiskt inte kan det, och det brukar inte vara så uppenbart att läsa sig till, utan kräver ofta debuggning för att försöka förtså vad det egentligen är för slags "Object" som kan komma att bli exekverade, och vilka krav som ställs på ett sådant Object för att det skall fungera så som kodskaparen hade tänkt sig.
/ TomasSv:Topp fem programmeringsriktlinjer?
Att använda Summary's är jättebra om man skriver ramverk som en tredjepart skall använda sig av eller om det i undantagsfall inte gått att beskriva vad metoden gör med namnet i det context som klassnamnet är.
Annars tycker jag att man kommer långt med att följa SOLID principerna för att få underhållbar kod vilket är det viktigaste i de flesta scenarion.Sv: Topp fem programmeringsriktlinjer?
Jag anser att du har fel, är man två eller flera som jobbar på en större mjukvara är summaries ett måste i kombination med tydliga metodnamn osv. Den mjukvaran jag jobbar i idag har 9 år på nacken, den består av ungefär 700000-800000 rader kod (den kompilerar över tjugo miljoner rader kod), delar av koden återanvänds i sex andra mjukvaror, vi är tre personer som arbetar med den, totalt har 8 personer arbetat med den (och övriga sex mjukvaror) och slutligen så driftas den skarpt ute hos 9000 kunder världen över, att nöja sig med tydliga metodnamn och tydliga parameternamn i en sådan miljö är att be om trubbel.Sv:Topp fem programmeringsriktlinjer?
Och jag tror fortfarande att man oftast når ända fram med bra metodnamn, klassnamn och parameternamn, samt att man följer SOLID principerna som begränsar klassernas storlek, samt att man komponentiserar allting vilket gör att det blir uppdelat på ett bra sätt.
Det kvittar om det driftas hos 9.000 kunder eller hur länge det har underhållits, metodnamnen blir inte mer intetsägande för det.
Nu säger jag inte att man inte får kommentera, men oftast när man känner för att kommentera så har man kan skrivit sin kod på ett mindre bra sätt.Sv: Topp fem programmeringsriktlinjer?
Det där är faktorer som spelar in väldigt mycket mer än vad du verkar tro, antalet kunder ökar kraven på driftsäkerhet och underhåll, kvaliten i de båda faktorerna begränsas av kodmängd och hur lättunderhållen koden är, hur lättunderhållen koden är oavsett kodmängd begränsas av hur väldokumenterad den är, hur väldokumenterad den är begränsas av hur lat utvecklare man är. Tydliga metodnamn håller jag med om att det är viktigt men den tydligheten begränsas av hur bra utvecklaren är på det gemensamma språket inom företaget, den metod som heter InvoiceHelper för mig heter kanske InvoiceRecalculation för någon annan, så därför är purpose-kommentarer alltid superviktig om man planerar att använda koden mer än en gång eller att underhålla den löpande.
Jag säger inte så här fritt gripet ur luften utan med flera års erfarenhet i större och mindre team i ryggen samt med flera års erfarenhet av mjukvaror med många kunder. Att jobba i ett team där folk byts ut löpande ställer krav på att koden är lättbegriplig och att den är väldokumenterad, annars får man spendera för mycket tid till att hjälpa folk komma igång i koden, namnet och innehållet i funktionerna hjälper bara till om man förstår syftet, förstår man inte det så är man inte behjälpt alls av übertydliga namn, och vem har tid att förklara syftet hela tiden?Sv:Topp fem programmeringsriktlinjer?
Sv: Topp fem programmeringsriktlinjer?
Sv:Topp fem programmeringsriktlinjer?
Sv: Topp fem programmeringsriktlinjer?
På min arbetsplats jobbar vi med flera olika metoder än så men det beror främst på att vi är ett industriföretag och har en ägare som tvingar oss att jobba enligt de metoder han är van vid.Sv:Topp fem programmeringsriktlinjer?
Jag vet att det är många utvecklare som känner frustration över att de inte kan få skapa perfekta lösningar men det är viktigt att veta att perfektion kostar oftast alldeles för mycket tid, pengar och kraft, och det är något som kunden väldigt sällan är beredd att betala eller bör vilja betala.