Jag stör mig ofta på den här typen av konstruktioner, <info> Du vill förmodligen bygga strategier istället. En strategi är ett så kalla design pattern och passar för komplexa vilkors-satser. <code> Jag brukar använda exceptions för felhanteringen när programspråket stöder det. Tänk på att exceptions är ett mycket långsamt sätt att styra flödet. >Tänk på att exceptions är ett mycket långsamt sätt att styra flödet. Hej Per! Angående exceptions: tror definitivt inte att det blir väsentligt långsammare, men i mitt tycke (och jag tror det var Scott Meyers som fick mig till den åsikten) så är det ändå ingen bra ide. Kristofer: Hej,If Then Else If Then Else If Then Else And Then, and then, and then, and then..
som jag själv hamnar i ibland.
Det är helt korrekt, och effektiv kod.. men jobbigt att läsa.
Plus att jag inte kan återanvända raden ( Print "Nej det går inte bra" )
Hur gör ni i liknande situationer?
Ex.
<code>
If KollaOmDetFinns(A) Then
If KollaBehorighet(AnvNamn, A) Then
If Cint(A) > 1000000 Then
Print "Nej det går inte bra" 'obs att detta återkommer....
Else
' Okej vi går vidare
DraIgångVärstaBatchjobbet()
End If
Else ' Att ändra häromkring är inte skoj !
Print "Nej det går inte bra" 'obs att detta återkommer....
End If
Else
Print "Nej det finns inte"
End If
</code>
Det borde finnas nåt kewlt pattern för den här typen av problem (en lång radda med en massa tjötiga villkor som måste finnas men som man vill hantera snyggare än så här....)
Jag är redan kompis med Refactoring..
ps
undrar om nån känner igen
and then, and then, and then.... ? ?
från en viss film.... ? =)
ds.Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
ps
undrar om nån känner igen
and then, and then, and then.... ? ?
från en viss film.... ? =)
ds.
</info>
Det är från "Dude, Where's My Car?"Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
Jag skulle göra så här:
pseudokod:
// Skicka alla parametrar till en strategi fabrik. Det spelar ingen roll vilken typ av parametrar det är.
// dvs det kan vara musklick, sträng från tangentbordet, httpd-anrop. Du abstraherar alla parametrar
// med en InputParameterHandler. Parametrarna kan definera ett "tillstånd", men ännu bättre är
// att använda en speciell tillståndsvariabel (stateObject).
strategyFactory = new StrategyFactory(new InputParameterHandler(**what ever input**),stateObject);
// Tillståndet (tillsammans med parametrarna) gör att du kan plocka ut en lämplig strategi:
strategy = strategyFactory->getStrategy();
// Varje strategi innehåller ett antal kontroller som fungerar som gränssnitt mellan användaren,
// dataprocesser eller vad som helst..
arrayOfControls = stragety->getControls();
// Kontrollerna måste in i någon form av loop där de kan rendreras, och samla parametrar som
// du sedan kan trycka in i InputParameterHandler ovan...
foreach arrayOfControls as control do
control->insertIntoDisplayCycle()
control->actOnInput()
end
Good luck :-)Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
If Not KollaOmDetFinns(A) OrElse _
Not KollaBehorighet(AnvNamn, A) OrElse _
Cint(A) > 1000000 Then
Print "Nej det går inte bra" 'obs att detta återkommer....
Else
' Okej vi går vidare
DraIgångVärstaBatchjobbet()
End If
</code>
En annan variant som jag gillar för att den är tydlig är att beta av valideringar först i subben och sedan utföra det som skall göras :
<code>
If Not KollaOmDetFinns(A) Then
Print "Nej det finns inte"
Exit Sub
End If
If Not KollaBehorighet(AnvNamn, A) Then
Print "Nej det går inte bra" 'obs att detta återkommer....
Exit Sub
End If
If Cint(A) > 1000000 Then
Print "Nej det går inte bra" 'obs att detta återkommer....
Exit Sub
End If
' Valideringar klara, utför uppgiften
' Okej vi går vidare
DraIgångVärstaBatchjobbet()
</code>Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
Din kod skulle då se ut så här
try
If Not KollaOmDetFinns(A) Then Throw FinnsInte
If Not KollaBehorighet(AnvNamn, A) Then Throw DetGarInteBra
If Cint(A) > 1000000 Then Throw DetGarInteBra
DraIgångVärstaBatchjobbet()
catch
Alla felmeddelanden på ett ställe
Ibland kan det ju bli lite grötigt med en massa try catch förståss.Sv:If Then Else If Then Else If Then Else And Then, and then, and then, and the
Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
Tja, långsamt är ju ett relativt begrepp. Exceptions är ju något som sker helt inneslutet i programmet utan några externa beroenden (utom möjligtvis en minnesallokering). Tiden för hanteringen av exceptions är ju helt försumbar i jämförelse med ett databasanrop eller att läsa en fil.
Dessutom tar ju exceptions i princip ingen extra tid förutom då man gör throw och felhanteringen är väl sällan en tidskritisk del av programmet.
Om man är orolig så kanske man inte skall använda exceptions i en väldigt tight loop men i övrigt ser jag ingen anledning till att skriva krångligare kod av prestandasjäl.
Datorerna hinner ju bli snabbare under den extra tid det tar att underhålla ett program med en massa if...then :-)Sv:If Then Else If Then Else If Then Else And Then, and then, and then, and the
Hur representerar du vilkorssatser som är i fler nivåer än en? Låt oss säga att du vid tillstånd X (till exempel klockan sju på morgonen) ska posta iväg tio epost beroende på systemstatus för din klustermaskin. Det nionde epostet triggar dessutom en underprocess som eventuellt kan posta iväg tio epost till.
Det verkar som att 'platta ut' alla vilkors-satserna inte förefaller vara en lönsamidé eftersom du bara skulle få hysteriskt stora _oindexerade_ listor utan någon möjlighet att betrakta inbördes beroende.
/KSv:If Then Else If Then Else If Then Else And Then, and then, and then, and the
Rangordningen för att hantera fel är snarare:
1. Kan man _lösa_ problemet, gör det.
2. Kan man inte lösa problemet, vidarebefordra det till någon som kan (uppåt i kedjan). I vissa fall vet man att anropande funktioner inte kan det, och då måste man vidarebefordra till användaren.
Slutsatsen är helt enkelt att alla kontroller man gör som sen kan kasta exceptions bör bara göra det om ens exceptions kommer komma ur funktionen.
Då vet man alltid att alla exceptions man fångar är från en funktion man har anropat, men som inte själv har kunnat lösa problemet.Sv: If Then Else If Then Else If Then Else And Then, and then, and then, and the
Jag är inte säker på att jag förstår vad du menar.
Exemplet som gavs innehöll tre nivåer av if-satser där varje nivå validerade något och om alla tre gick igenom så utfördes en och endast en uppgift. I det fallet så finns det ingen anledning enligt mig skriva detta som tre nästlade if-satser, då läsbarheten försämras.
Anledningen till att jag gör så när det är applicerbart är bl a Design-by-contract-tänket som finns i t ex Eiffel, där varje funktion börjar med att försäkra sig om att indatan är korrekt, sedan utförs uppgiften och därefter valideras även utdatan. Detta är ett bra och tydligt mönster som fler borde anamma.
Jag menar inte att man kan eller ska platta ut alla if-satser på det viset, men i det specifika exemplet så tycker jag det är en bra lösning. Exempel på if-satser jag antagligen inte skulle platta ut är :
<code>
if VillkorA then
if VillkorB then
' Utför uppgift 1
else
' Utför uppgift 2
end if
else
if VillkorC then
' Utför uppgift 3
else
' Utför uppgift 4
end if
end if
</code>Sv:If Then Else If Then Else If Then Else And Then, and then, and then, and the
En tanke kring problematiken att samma funktion anropas från flera olika else satser samtidigt som detta försämrar läsbarheten brukar jag lösa på följande sätt:
<code>
FunktionExekverad = False
If VillkorA Then
If VillkorB Then
' Utför uppgift 1
FunktionExekverad = True
End If
Else
If VillkorC Then
' Utför uppgift 2
FunktionExekverad = True
End If
End If
If Not FunktionExekverad Then
'Utför fel-funktion
End If
</code>
Visst, det blir någon bårkdels sekund prestandaförlust, eftersom ett extra villkor utförs, men istället med fördelen att koden blir mer läsbar och att man inte behöver ändra på mer än ett ställe om man döper om sin felfunktion, ändrar parametrar osv.
EDIT:
Vill man sedan som i allra första inlägget jobba med flera olika felvarianter, men som ändå är återkommande (typen "nej det finns inte" och "nej det går inte"), så kan man iställer för en boolean använda en numerisk variabel som signalerar status som i sin tur är inparameter till sin fel-hanteringsrutin.
// Johan