webForumDet fria alternativet

Singleton eller inte?

58 svar · 2 969 visningar · startad av Lukaspojken · sida 2 av 3

NickemannenMedlem sedan aug. 20003 575 inlägg
#21

Lukaspojken skrev:

>Nickemannen: ...att det blir mer kod tror jag inte heller.

Om du tex skapar ett interface till en entitet eller till ett repository hur gör du då för att det inte skulle bli mer kod än om du skulle skipa köra med interface? Vi säger att du har ett repository inteface som tex kräver att GetById, PersistAll m.m. är med. Genom att du bara skapar interfacet så har du mer kod, eller?

Jag anser att det blir mindre kod att underhålla eftersom du efter ett par års användning av ditt system har byggt in dig i ett hörn med att ditt system är hårt kopplat så att du måste göra "fulhack" lite här och där om du fortfarande skall hålla effektiviteten uppe. Fulhacken kommer i framtiden leda till mer och komplexare kod.
Initialt blir det lite mer kod, men du vinner med lösbarhet och testbarhet samt komplexitet.
Och i framtiden kommer detta att löna sig i mindre och underhållsvänligare kod, och det är ju underhållet av en applikation där kostnaden ligger.

På dina entiteter kan som du säger kan dock interface vara overkill, utan det brukar mest handla om infrastruktursaker, som repositories, services osv men ibland även entiteter.

LukaspojkenMedlem sedan maj 20011 312 inlägg
#22

-> Gladh
>Ja det kvittar vad du kallar, jag visade bara på ett exempel där man vill få bort att man hämtar data i dess "riktiga" miljö eftersom det skulle bli extremt långsama tester.

LP: Jag vet inte om jag är otydlig :) Men integrationswrappern gör dina tester snabba eftersom det mockar dina objekt om du vill det. Alltså testerna är inte långsamma.

>Det där var inte mycket till exempel, hur vet din basklass att det är ett test som jag gör eller om det är ett anrop i produktion? Och nej preprocessor direktivet #Ifdebug är inte att rekomendera...

LP: Det finns många sätt att hantera detta på. Jag skulle inte använt mig av IfDebug. För det kan ju vara så att du vill ha databaskoppling i debug och inte mocka allt :) En väldigt enkelt sätt som jag gjorde var att skapa en inställning i config-filen som tex angav om det skulle mockas, skapas mock objekt dynamiskt, traca eller om datan tex skulle hämtas från databasen. Sedan kan man lägga på lite ytterligare alternativ som tex att mock objekten ska sparas i databasen, fil eller minnet m.m. Jag testade att spara mock objektet i databasen och läsa in det i minnet.

>Dessutom så kan du ju ha olika unittester som skall returnera olika resultat, hur implementerar du det i din basklass?

LP: Detta löste jag också lite lätt genom att spara det mockade objektet samt inparametrarna till metoden (inparametrarna blev nyckeln till ett specifikt mockobjekt) men det fanns en möjlighet att man kunde skipa nyckeln och använda sig av ett och samma mock objekt. Eller att man använda sig av ett default mockobjekt om man inte fick en träff på nyckeln.

>Det är inte speciellt ofta man byter databas, men det är betydligt oftare som man kanske byter sin OR/Mapper, man byter ut sin Loggingklass, man kan ha referenser till externa system via webservices eller WCF som byts ut ganska ofta.

LP: Vilket företag jobbar du på som byter OR-Mapper ofta i applikationen? :) Loggingklass har jag aldrig behövt byta ut under de snart 10 år jag jobbat (alltså inom en applikation). Det som dock hänt är att jag velat logga mer men det har inte påverkat applikationens loggdel något eller applikationen i övrigt stort. När jag började använda mig av en integrationswrapper så ville jag logga mer vid integrationsfel som tex sql-kommandot med dess inparametrar. Riktigt nice. Jag har också byggt det så att det är möjligt att traca och se exekueringstider på olika sql-kommandon (ungefär som SQL profiler) fast en light variant och som inte kräver rättigheter på SQL servern för att man ska behöva köra det. För det är inte ovanligt att SQL profiler är spärrad på tex produktionsservern.

En annan intressant sak som jag gjorde apropå stordator var att bygga en liten integrationswrapper runt stordatorkopplingar. Genom detta kunde jag enkelt traca m.m. vad som skickades in och ut. Jag byggde också en bra koppling mot stordatorns autogenererade gränssnitt. Denna funktionalitet var väldigt omtyckt av stordator-folket vilket underlättade deras arbete väldigt mycket. Det underlättade även .Net-teamens arbete.

>Att få ett löstkopplat system med en sådan liten kostnad som DI innebär, är värt det, speciellt ju större system och ju längre tid de skall leva. Det är min erfarenhet!

LP: Jag säger inte att DI är dåligt i alla avseenden. Det jag säger är att det finns alternativ till hur olika problem kan lösas.

  1. Om syftet med DI är att undvika integrationstester eftersom de är långsamma då finns det alternativ att använda sig av som tex en integrationswrapper. Genom detta erhåller du djupare tester än vad enhetstester och DI skulle kunna ge utvecklaren. Det räcker också att du skapar ett enda test för både integrationstest och icke-integrationstest. Via en enkel inställning så väljer du att tex köra lokalt icke-integrationstester för att snabbt erhålla feedback på det du gör. Exakt samma tester kan därefter köras på en byggserver fast med en annan inställning, dvs med integrationskoppling. Fördelen är att du har färre tester att förvalta samt att du erhåller snabbhet, djupare tester samt möjligheten till integrationstest i ett och samma test.
  2. Om syftet med DI är att löskoppla systemet så finns det olika nivåer man kan löskoppla det på. Om du löskopplar på områden som du aldrig har ett behov att löskoppla då är det slöseri med kundens pengar. Det kan vara svårt att avgöra i vissa fall vad som bör löskopplas och inte men genom erfarenhet bygger man upp en känsla för detta. Håller du med om att det är slöseri med kundens pengar om du löskopplar för mycket och aldrig behöver använda det?

>Det håller jag med dig i, det finns ju fortfarande folk som inte tagit till sig sådan enkla hjälpmedel som DI... "Ledsen kunde inte låta bli"

LP: Hehe, jag tar till mig DI i de sammanhang jag tycker det är vettigt att implementera det men jag implementera det inte överallt och jag ser att det finns bättre alternativ till DI vissa avseenden. Att implementera DI överallt för att det går tycker jag inte visar på hög kompetens :)

NickemannenMedlem sedan aug. 20003 575 inlägg
#23

Men, ta din fråga högst upp i tråden. Du vill ha en singleton för att lösa ditt problem, men singleton fungerar oftast inte bra i system där flera trådar kommer att arbeta mot singleton.

Istället för att meka med att kolla vilken tråd som anropar, lagra saker i context's så löser du det väldigt fint med DI då du inte ens behöver tänka på trådar. (någonstans behöver du göra det, men inte på många ställen).

Här tycker jag man gör en stor vinst mot komplexiteten genom att använda DI.

Jag tycker inte DI är överdesign, bara för att man använder DI betyder inte att man måste använda sig av interface, dock så blir det enkelt att testa om du har interface men man måste inte.

LukaspojkenMedlem sedan maj 20011 312 inlägg
#24

>Nickemannen: Jag anser att det blir mindre kod att underhålla eftersom du efter ett par års användning av ditt system har byggt in dig i ett hörn med att ditt system är hårt kopplat så att du måste göra "fulhack" lite här och där om du fortfarande skall hålla effektiviteten uppe. Fulhacken kommer i framtiden leda till mer och komplexare kod.

LP: Detta håller jag inte med om. Om förhållningssättet är att man ska göra fulhack då får man fulhack. Fulhack ska dock ses som en teknisk skuld och åtgärdas och inte sopas under mattan. I Scrum så skulle du kunna lägga fulhack som ett produkt backlog item som måste åtgärdas. Så det argumentet håller inte :)

>Nickemannen: På dina entiteter kan som du säger kan dock interface vara overkill, utan det brukar mest handla om infrastruktursaker, som repositories, services osv men ibland även entiteter.

Nu är jag lite hård :) Det är intressant att du tycker att det är overkill att använda interface på entiteter. Men är det inte bra att kunna löskoppla dessa och förbättra testbarheten där också?

LukaspojkenMedlem sedan maj 20011 312 inlägg
#25

>Istället för att meka med att kolla vilken tråd som anropar, lagra saker i context's så löser du det väldigt fint med DI då du inte ens behöver tänka på trådar. (någonstans behöver du göra det, men inte på många ställen).

LP: Hur skulle detta underlätta ett anrop till tex metoden GetOrderById?

Jag gillar Gladhs exempel men det kan som sagt skapa problem om det används fel.

public class OrderRepository{
  public static GetNewInstance(){
    return new OrderRepository();
  }
}

Order order = OrderRepository.GetNewInstance().GetById(orderId);

Men vad var problemet med denna approach. Dottern ropar på mig måste sluta :)

>Nickemannen: Jag tycker inte DI är överdesign, bara för att man använder DI betyder inte att man måste använda sig av interface, dock så blir det enkelt att testa om du har interface men man måste inte.

LP: Alternativet är någon form av arvstruktur för att hantera det, eller?

NickemannenMedlem sedan aug. 20003 575 inlägg
#26

Lukaspojken skrev:

>Istället för att meka med att kolla vilken tråd som anropar, lagra saker i context's så löser du det väldigt fint med DI då du inte ens behöver tänka på trådar. (någonstans behöver du göra det, men inte på många ställen).

LP: Hur skulle detta underlätta ett anrop till tex metoden GetOrderById?

Jag gillar Gladhs exempel men det kan som sagt skapa problem om det används fel.

public class OrderRepository{
  public static GetNewInstance(){
    return new OrderRepository();
  }
}

Order order = OrderRepository.GetNewInstance().GetById(orderId);

Men vad var problemet med denna approach. Dottern ropar på mig måste sluta :)

>Nickemannen: Jag tycker inte DI är överdesign, bara för att man använder DI betyder inte att man måste använda sig av interface, dock så blir det enkelt att testa om du har interface men man måste inte.

LP: Alternativet är någon form av arvstruktur för att hantera det, eller?

Tja och repository i sin tur behöver ju en IDBConnection av ngt slag eller ISession för att kunna komma åt databasen dvs..

new XXXRepository(ISession session)

Om du skulle köra med ett DI verktyg så skulle du kunna få in den enkelt :)

LukaspojkenMedlem sedan maj 20011 312 inlägg
#27

Ok, jag trodde du menade att man kunde köra DI utan interface helt.

GladhMedlem sedan maj 20012 812 inlägg
#28

lukaspojken skrev:

LP: Jag vet inte om jag är otydlig Men integrationswrappern gör dina tester snabba eftersom det mockar dina objekt om du vill det. Alltså testerna är inte långsamma.

Nej då du var inte otydligt, du lägger mocken i din integrationswrapper, det är du som skriver wrapper som även skriver vilka testfall som det finns. Problemet jag ser här är att testdatan inte finns samlad på samma ställe som självatestet, och personen som skriver testet kan inte påverkar testdatan!

lukaspojken skrev:

LP: Det finns många sätt att hantera detta på. Jag skulle inte använt mig av IfDebug. För det kan ju vara så att du vill ha databaskoppling i debug och inte mocka allt En väldigt enkelt sätt som jag gjorde var att skapa en inställning i config-filen som tex angav om det skulle mockas, skapas mock objekt dynamiskt, traca eller om datan tex skulle hämtas från databasen. Sedan kan man lägga på lite ytterligare alternativ som tex att mock objekten ska sparas i databasen, fil eller minnet m.m. Jag testade att spara mock objektet i databasen och läsa in det i minnet

Ahhh, hederliga config-filen som skall berätta för dig om du skall köra test eller i produktion, been there, och det är inte kul att upptäcka att man pekar ut testdatabasen i produktionsmiljö.... (det var inte mitt fel, men ändå jag som fick jobba extra för att hitta problemet varför vi fick konsiga värden i produktion). Och det har hänt mer än en gång... så nu för tiden så skall all kod som jag skriver skrivas för produktion och vill jag något annat så får jag skriva kod för att komma runt produktionen. Och nej jag får inga problem med att jag skriver i produktion från utvecklingsmiljön efter som jag som utvecklare inte har rättigheter till produktionsmiljön.

lukaspojken skrev:

Vilket företag jobbar du på som byter OR-Mapper ofta i applikationen? Loggingklass har jag aldrig behövt byta ut under de snart 10 år jag jobbat (alltså inom en applikation). Det som dock hänt är att jag velat logga mer men det har inte påverkat applikationens loggdel något eller applikationen i övrigt stort.

Danskt företag som gick från egen utvecklad OR/Mapper och logginklass till använda färdiga som finns på nätet. Det blev en hel del om kodande av appliaktioner eftersom dessa inte hade interface och DI, utan referenser till de olika objekten. Många timmar som gick åt där...

- M

NickemannenMedlem sedan aug. 20003 575 inlägg
#29

Gladh skrev:

Danskt företag som gick från egen utvecklad OR/Mapper och logginklass till använda färdiga som finns på nätet. Det blev en hel del om kodande av appliaktioner eftersom dessa inte hade interface och DI, utan referenser till de olika objekten. Många timmar som gick åt där...
- M

Vilken bytte ni till? :)

GladhMedlem sedan maj 20012 812 inlägg
#30

NHibernate... Men hade det varit idag så hade de säkert blivit EF, och det är möjligt att de kommer byta till den när väl 2.0 kommer ut (om de inte redan har det), eftersom de gärna körde MS produkter rakt igenom.

Loggingenklassen var log4net som de implementerade istället för sin egen loggingklass.

Kanske skall påpeka att man byte inte överallt direkt, utan det som fanns i produktion där lät man det vara fram tills dess att man skulle göra någon större förändring, men alla projekt som var under utveckling skulle byta. Och kör man agile så kommer detta ske mer och mer, då man hela tiden skall finjustera/refaktorisera sin applikation.

- M

LukaspojkenMedlem sedan maj 20011 312 inlägg
#31

>Gladh: Problemet jag ser här är att testdatan inte finns samlad på samma ställe som självatestet, och personen som skriver testet kan inte påverkar testdatan!

LP: Detta löser man med ett simpelt administratörsgränssnitt mot de mockade objekten som finns. Antingen kan man autogenera mockade objekt från tex databasen, skapa egna eller autogenera och därefter manipulera dessa. Så det bör inte vara något problem. Man skulle också kunna bygga en VS addin som är integrerade med testdelen.

>Gladh: Ah, hederliga config-filen som skall berätta för dig om du skall köra test eller i produktion, been there, och det är inte kul att upptäcka att man pekar ut testdatabasen i produktionsmiljö.... (det var inte mitt fel, men ändå jag som fick jobba extra för att hitta problemet varför vi fick konsiga värden i produktion). Och det har hänt mer än en gång... så nu för tiden så skall all kod som jag skriver skrivas för produktion och vill jag något annat så får jag skriva kod för att komma runt produktionen. Och nej jag får inga problem med att jag skriver i produktion från utvecklingsmiljön efter som jag som utvecklare inte har rättigheter till produktionsmiljön.

LP: Det finns som sagt olika lösningar var man sparar inställningen. Jag gjorde det i config-filen i detta fallet och det fungerade helt ok.

>Gladh: Danskt företag som gick från egen utvecklad OR/Mapper och logginklass till använda färdiga som finns på nätet. Det blev en hel del om kodande av appliaktioner eftersom dessa inte hade interface och DI, utan referenser till de olika objekten. Många timmar som gick åt där...

LP: Hur lång tid skulle det tagit mindre om ni kört DI? Gör en grov uppskattning. Hur lång tid tog det ungefär nu utan DI? Nu vill jag se stora skillnader :) Om ni ofta byter tekniker så kan det finnas en intressant källa till varför ni gör. Att förstår var förändringen kommer ifrån skulle jag rekommendera att man tittar närmare på. Är det tex någon som driver på nya tekniker för att det är coolt och häftigt (många gör det och många glömmer bort affärsnyttan samt vad en förändring egentligen innebär). Angående EF, jag skulle inte rekommendera att hoppa på EF-tåget än för det är för nytt och kommer att ha en del barnsjukdomar en tid framöver. Ha tålamod och använd Nhibernate ett tag till och när EF är moget och ni känner att ni skulle erhålla ett mycket större mervärde att börja använda det då ska ni byta. Men byt inte OR-mapper bara för att det ger en liten förbättringspotential. Det blir svårt att räkna hem sådana förändringar.

GladhMedlem sedan maj 20012 812 inlägg
#32

lukaspojken skrev:

LP: Det finns som sagt olika lösningar var man sparar inställningen. Jag gjorde det i config-filen i detta fallet och det fungerade helt ok.

Det spelar ingen roll var du spara dem, om du måste se till att ändra på dem mellan olika miljöer så kommer det förr eller senare leda till att du råkar ha fel parameters, och då kan man bara hoppas på att den användare som används inte har rättigheter till den felaktiga miljön, så blir skador mindre... bara ett lite avbrott i produktionsmiljön.

lukaspojken skrev:

LP: Detta löser man med ett simpelt administratörsgränssnitt mot de mockade objekten som finns. Antingen kan man autogenera mockade objekt från tex databasen, skapa egna eller autogenera och därefter manipulera dessa. Så det bör inte vara något problem. Man skulle också kunna bygga en VS addin som är integrerade med testdelen

Du tycker att DI är onödigt komplext för att användas vid tester, men kan tänka dig att bygga adminstrationsverktyg eller addins till VS för att kunna hålla reda på dina mockade objekt. När du lika gärna kan ha de i själva unittesten.... Snacka om att gå över ån efter vatten.

lukaspojken skrev:

Är det tex någon som driver på nya tekniker för att det är coolt och häftigt

Nej då, det var ett beslut som togs då man valde att minska Java-satsningen i huset och utveckla mer i .NET. Och då java delen var vana vid Hibernate så togs beslutet att det skulle användas som inom .NET också, lika så log4Net. Det var ett politisk beslut och eftersom MS inte hade någon ORMapper så valde man att gå java-utvecklarna till mötes...

lukaspojken skrev:

LP: Hur lång tid skulle det tagit mindre om ni kört DI? Gör en grov uppskattning. Hur lång tid tog det ungefär nu utan DI? Nu vill jag se stora skillnader

oj det kommer jag inte ihåg det är mer än 2 år sedan... Men skillnaden hade varit enorm, att ha ett ställe att ändra på eller upp mot tusentals som det var i något riktigt stort projekt. Det gällde loggingen, att byta ORMapper hade tagit ordentligt med tid i vilket fall som helst eftersom man gick ifrån attribute i klassen till att använda xml-filer.

Sedan så är jag fortfarande nyfiken på hur koden för en integrationswrapper ser ut men misstänker att jag inte får ser något, vilket gör det lite svårt att utvärdera hur bra den skulle kunna platsa in i min utveckling.

- M

LukaspojkenMedlem sedan maj 20011 312 inlägg
#33

>Gladh: Det spelar ingen roll var du spara dem, om du måste se till att ändra på dem mellan olika miljöer så kommer det förr eller senare leda till att du råkar ha fel parameters, och då kan man bara hoppas på att den användare som används inte har rättigheter till den felaktiga miljön, så blir skador mindre... bara ett lite avbrott i produktionsmiljön.

LP: Det problemet har man med det mesta gällande config-filer och annat. En enkel lösning som jag fixade till en gång var ar att man enkelt kunde se tex vilken databaskoppling m.m. varje miljö hade om man loggade in som en förvaltningsanvändare. Jag har aldrig dock hamnat i det problemet med att publicera ut fel config-inställningar men denna funktionalitet som jag byggde skulle ha hjälpt en hel del att hantera sådana problem. Jaja, det är en annan fråga.

>Gladh: Du tycker att DI är onödigt komplext för att användas vid tester, men kan tänka dig att bygga adminstrationsverktyg eller addins till VS för att kunna hålla reda på dina mockade objekt. När du lika gärna kan ha de i själva unittesten.... Snacka om att gå över ån efter vatten.

LP: Det jag säger är att använd DI när det behövs inte överallt bara för att det går. Löskoppla alltså inte allt bara för att det går. Sedan kan en integrationswrapper ge en hel del andra möjligheter som DI inte ger som tex djupare automatiska tester, mindre kod, större återanvändningsbarhet m.m. DI är alltså inte "onödigt komplext". Det finns bara områden där en integrationswrapper är bättre än DI. DI är inte en silver bullet.

>Gladh: oj det kommer jag inte ihåg det är mer än 2 år sedan... Men skillnaden hade varit enorm, att ha ett ställe att ändra på eller upp mot tusentals som det var i något riktigt stort projekt. Det gällde loggingen, att byta ORMapper hade tagit ordentligt med tid i vilket fall som helst eftersom man gick ifrån attribute i klassen till att använda xml-filer.

LP: Det är det jag är vill trycka på. Det största arbetet går till att tex skapa den nya lösningen. Inte att replace kopplingen från den gamla. Loggdelen skulle jag nog kunna bytt ut snabbt om ni inte krånglat till det alltför mycket :) OR-mappern skulle nog inte tagit så lång tid heller utan det som tar tid är att skapa mappningen på nytt m.m. och detta hjälper inte DI med.

>Gladh: Sedan så är jag fortfarande nyfiken på hur koden för en integrationswrapper ser ut men misstänker att jag inte får ser något, vilket gör det lite svårt att utvärdera hur bra den skulle kunna platsa in i min utveckling.

LP: Det jag gjort är inte klart och det uppfyller så mycket annat än bara att att enkelt switcha mellan integrationstester, djupare enhetstester utan integrationskopplingar. Men någon dag kanske vi kan ta och vidareutveckla detta tillsammans med lite folk om du är intresserad. Just nu har jag en hel del att göra så jag hinner inte starta ett sådant "hobbyprojekt" :)

GladhMedlem sedan maj 20012 812 inlägg
#34

lukaspojken skrev:

Loggdelen skulle jag nog kunna bytt ut snabbt om ni inte krånglat till det alltför mycket

Om vi inte heller hade krånglat till det med hårda reference och avsaknaden av interface (men precis som du, så var det någon som tyckte det var jobbigt att man inte kunde trycka F12 i utvecklingsmiljön...), så hade vi enkelt också kunnat byta ut den snabbt...

Problemet var ju att vi hade kod som ser ut så här.

myLog.Message(Level.Debug, "Kalle testar");

Denna kod där log är en referens till egenutvecklad komponent skall bytas ut mot kod som ser ut så här.

log4net.Debug("Kalle testar");

Efter som myLog är en referens så måste du gå in och ändra på varje ställe där denna kod finns i hela ditt projekt. Om myLog istället hade varit ett interface så hade du bara skapat en ny klass som hade wrappat runt log4net och du hade fått kod som sett ut så här:

public class Log4NetWrapper : IOurOwnLogging
{
       public void Message(LogLevel logLevel, string message)
       {
             If(logLevel == LogLevel.Debug)
                 log4net.Debug(message);
             ...
       }
}

Betydligt mycket enklare, och framför allt mycket kortare tid, sedan in i din config-fil / i koden och ändra så att IOurOwnLogging interfacet kommer att mappa mot vår nya klass istället för den gamla.

DI i detta läget ger dig fördelen att du ändrar på 1 ställe istället för vid varje instansiering, interfacet ger dig fördelen att du enkelt kan wrappa din kod.

LP: Det jag gjort är inte klart och det uppfyller så mycket annat än bara att att enkelt switcha mellan integrationstester, djupare enhetstester utan integrationskopplingar. Men någon dag kanske vi kan ta och vidareutveckla detta tillsammans med lite folk om du är intresserad. Just nu har jag en hel del att göra så jag hinner inte starta ett sådant "hobbyprojekt"

Du verkar ju redan säker på din sak att din wrapper är bättre an vad DI är så du måste ju ha något att visa. Och utan att se koden så har du svårt att övertyga mig om att wrapper skulle vara en bättre lösning än DI.

Men är du nöjd med den så använd den vidare, jag kommer fortsätta med DI, och det är det som är härligt med programmering, olika personer har olika lösningar på problemen och det är det som driver utvecklingen framåt.

- M

LukaspojkenMedlem sedan maj 20011 312 inlägg
#35

LP: Om det är en referens som Mylog pekar på då blir det jobbigare. Jag brukar dock skapa en wrapper (integrationswrapper) runt tex loggning, databaskoppling m.m. och då vinner du inte så jättemycket på att använda interface. Skulle du byta myLog.Message(Level.Debug, "Kalle testar") till log4net.Debug("Kalle testar") då är det bara att skapa en ny metod i din wrapper som heter debug. Ta bort den gamla som heter Message. Bygga och sedan fixa felen. Högst 0,5-1 timmarsarbete per projekt. Det som tar tid är att fixa till logiken Debug-metoden men denna tid kommer man inte ifrån oavsett om man använder DI eller inte. Håller du inte med om det i detta fallet?

>Gladh: Du verkar ju redan säker på din sak att din wrapper är bättre an vad DI är så du måste ju ha något att visa. Och utan att se koden så har du svårt att övertyga mig om att wrapper skulle vara en bättre lösning än DI.

LP: Vad är det du inte förstår utan att se på koden? Koden tillhör företaget jag jobbar på och den kan jag inte bara lägga ut även om jag skulle vilja.

>Gladh: Men är du nöjd med den så använd den vidare, jag kommer fortsätta med DI, och det är det som är härligt med programmering, olika personer har olika lösningar på problemen och det är det som driver utvecklingen framåt.

LP: En så länge är jag nöjd och de behov jag haft har den löst på ett bra sätt. Sedan kan man alltid förbättra integrationswrappern ytterligare som med mycket annat.

GladhMedlem sedan maj 20012 812 inlägg
#36

lukaspojken skrev:

Om det är en referens som Mylog pekar på då blir det jobbigare.

Vilket det brukar var i 95% av fallen om du inte använder DI (vilket tvingar utvecklaren att utveckla mot interface istället för klasser).

lukaspojken skrev:

Jag brukar dock skapa en wrapper (integrationswrapper) runt tex loggning, databaskoppling m.m. och då vinner du inte så jättemycket på att använda interface.

Du skapar alltså ett eget gränssnitt runt loggingen, men väljer hellre att göra det som ett objekt än ett interface.

lukaspojken skrev:

Skulle du byta myLog.Message(Level.Debug, "Kalle testar") till log4net.Debug("Kalle testar") då är det bara att skapa en ny metod i din wrapper som heter debug. Ta bort den gamla som heter Message. Bygga och sedan fixa felen. Högst 0,5-1 timmarsarbete per projekt. Det som tar tid är att fixa till logiken Debug-metoden men denna tid kommer man inte ifrån oavsett om man använder DI eller inte. Håller du inte med om det i detta fallet?

Jodå det blir ungefär samma arbetsbörda, eftersom du wrapper loggingklassen med din egen wrapper. Dock inte lika snyggt som om du gjort det med ett interface, men är F12 viktig för dig så är den.

- M

LukaspojkenMedlem sedan maj 20011 312 inlägg
#37

>Gladh: Vilket det brukar var i 95% av fallen om du inte använder DI (vilket tvingar utvecklaren att utveckla mot interface istället för klasser).

LP: Har du några andra fall som du använder DI än db-kopplingar och logging för den hantering jag har idag klarar förändringar skapligt bra plus att jag får en massa annan mervärde. Webservice och WCF lösningar skulle kunna vara ett område alternativ. Jag har tittat lite snabbt på detta område och jag tror att det inte var så svårt att fixa till en integrationswrapper för det.

>Gladh: Du skapar alltså ett eget gränssnitt runt loggingen, men väljer hellre att göra det som ett objekt än ett interface.

LP: Lite förenklat kan man säga att ett interface är dumt medan en integrationswrapper kan tillföra en större mervärde genom att tex erbjuda djupare automatiska tester m.m.

>Gladh: Jodå det blir ungefär samma arbetsbörda, eftersom du wrapper loggingklassen med din egen wrapper. Dock inte lika snyggt som om du gjort det med ett interface, men är F12 viktig för dig så är den.

LP: Intressant att du tycker att arbetsbördan ungefär är detsamma (för jag håller helt med dig men jag trodde inte du skulle erkänna det)! :) Det med F12 är ETT argumentet för att använda en integrationswrapper men det är långt ifrån den enda, det är allstå inte det enda syftet till varför jag använder mig av en integrationswrapper som sagt. Det finns så mycket annat en integrationswrapper ger som tex underlätter felsökning, felhantering, tracing, mockning, autogenering av mockade objekt, färre tester genom att enhetstester och integrationstester samkör samma metoder och en inställning styr vad det är för tester som ska köras, man erhåller djupare tester, möjlighet till tex sql-validering, slipper problem med F12-funktionalitet, större återanvändningbarhet m.m. Den ger också ett hyffsat bra stöd för löskoppling av integrationsdelar. Så om man ska betygsätta en integrationswrappern så får den generellt ett högre betyg än DI :)

PhorpherMedlem sedan feb. 20002 300 inlägg
#38

Lukaspojken:
Om du inte kan lämna ut företagshemligheter kan du väl ge ett schematiskt exempel eller pseudokod på en integrationswrapper? Jag har försökt söka lite på termen men kan inte direkt påstå att jag blivit klokare eller överhuvudtaget hittat något vettigt om det. Finns det en engelsk term för det som jag missat?

CatZMedlem sedan jan. 20022 440 inlägg
#39

För att återkoppla till ämnet! Ända gången jag använder en singelton är för att hålla ett 10 MB stort xml dokument i minnet (http://wurfl.sourceforge.net/). Kom inte på någon bättre lösning. Alla detections vi gjorde utan singelton resulterade i att massvis med besökare kändes igen som samma mobiltelefon och jag ville inte gärna instantiera obegränsat med 10MB stora xml dokument i minnet.

Jag utmanar er att försöka hitta en annan lösning på det problemet! :e

PhorpherMedlem sedan feb. 20002 300 inlägg
#40

CatZ skrev:

För att återkoppla till ämnet! Ända gången jag använder en singelton är för att hålla ett 10 MB stort xml dokument i minnet (http://wurfl.sourceforge.net/). Kom inte på någon bättre lösning. Alla detections vi gjorde utan singelton resulterade i att massvis med besökare kändes igen som samma mobiltelefon och jag ville inte gärna instantiera obegränsat med 10MB stora xml dokument i minnet.

Jag utmanar er att försöka hitta en annan lösning på det problemet! :e

Hmm. Varför slutade ni få de felen bara för att ni skötte identifieringen genom ett Singelton? Eller var det någon egenutvecklad id-metod som gav felen?

Ett alternativ vore kanske att registera en "mobilidentifierings-service" i en DI-container och sätta livslängden på servicen till en Singleton (t.ex. i Unity med ContainerControlledLifetimeManager.)

145 ms totalt · 3 externa anrop · v20260731065814-full.beb2e261
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
142 ms — hämta tråd, inlägg och bilagor (db)