How Jennifer Garner REALLY feels about 'rekindling' romance with Ben Affleck 10 years after nanny cheating scandal
Father of British POW, 22, jailed for 19 years by Russian court for fighting for Ukraine fears his son's 'life is over'
Arrest after reports of man 'exposing himself' at Essex town car park
'Family warned me against Turkey surgery after I lost 16stone'
Fury at 'two-tier' justice move that means 'ethnic and faith minorities are less likely to go to prison': Tories warn courts could become 'anti-white and anti-Christian'
Gene Hackman friend reveals why two of star's dogs survived, as mystery over dead dog deepens
Asylum seeker raped girl, 15, in town centre after spotting her alone, court hears
Satnav systems built for Earth used by Blue Ghost lander as it approached the Moon
An experimental module attached to Firefly Aerospace's Blue Ghost Moon lander successfully used Earth's orbiting satnav systems, a feat that suggests a specialized lunar positioning system may not be needed.…
JENNI MURRAY: One friend's son is struggling with drugs. Another is in terrible debt. We're failing a generation of young men... and there's a devastating cause
Jose Mourinho: Born in Portugal. Made in Largs. What are the Special One's links to a quaint Scottish seaside town?
Paris Jackson goes braless in a black sheer gown as she joins leather-clad Kate Moss and Cameron Diaz at the Stella McCartney show during Paris Fashion Week
CodeSOD: An Argument With QA
Markus does QA, and this means writing automated tests which wrap around the code written by developers. Mostly this is a "black box" situation, where Markus doesn't look at the code, and instead goes by the interface and the requirements. Sometimes, though, he does look at the code, and wishes he hadn't.
Today's snippet comes from a program which is meant to generate PDF files and then, optionally, email them. There are a few methods we're going to look at, because they invested a surprising amount of code into doing this the wrong way.
protected override void Execute() { int sendMail = this.VerifyParameterValue(ParamSendMail); if (sendMail == -1) return; if (sendMail == 1) mail = true; this.TraceOutput(Properties.Resources.textGetCustomerForAccountStatement); IList<CustomerModel> customers = AccountStatement.GetCustomersForAccountStatement(); if (customers.Count == 0) return; StreamWriter streamWriter = null; if (mail) streamWriter = AccountStatement.CreateAccountStatementLogFile(); CreateAccountStatementDocumentEngine engine = new CreateAccountStatementDocumentEngine(); foreach (CustomerModel customer in customers) { this.TraceOutput(Properties.Resources.textCustomerAccountStatementBegin + customer.DisplayName.ToString()); // Generate the PDF, optionally send an email with the document attached engine.Execute(customer, mail); if (mail) { AccountStatement.WriteToLogFile(customer, streamWriter); this.TraceOutput(Properties.Resources.textLogWriting); } } engine.Dispose(); if (streamWriter != null) streamWriter.Close(); }Now, this might sound unfair, but right off the bat I'm going to complain about separation of concerns. This function both generates output and emails it (optionally), while handling all of the stream management. Honestly, I think if the developer were simply forced to go back and make this a set of small, cohesive methods, most of the WTFs would vanish. But there's more to say here.
Specifically, let's look at the first few lines, where we VerifyParameterValue. Note that this function clearly returns -1 when it fails, which is a very C-programmer-forced-to-do-OO idiom. But let's look at that method.
private int VerifyParameterValue(string name) { string stringValue = this.GetParam(name, string.Empty); bool isValid = this.VerifyByParameterFormat(name, stringValue); if (!isValid) return -1; int value = -1; try { value = Convert.ToInt32(stringValue); } catch (Exception e) { this.TraceOutput(string.Concat("\n\n\n", e.Message, "\n\n\n")); return -1; } return value; }We'll come back to the VerifyByParameterFormat but otherwise, this is basically a wrapper around Convert.ToInt32, and could easily be replaced with Int32.TryParse.
Bonus points for spamming the log output with loads of newlines.
Okay, but what is the VerifyByParameterFormat doing?
private bool VerifyByParameterFormat(string name, string value) { string parameter = string.Empty; string message = string.Empty; if (value.Length != 1) { parameter = Properties.Resources.textSendMail; message = string.Format(Properties.Resources.textSendMailNotValid, value); this.TraceOutput(string.Concat("\n\n\n", message, "\n\n\n")); return false; } string numbers = "0123456789"; char[] characters = value.ToCharArray(); for (byte i = 0; i < characters.Length; i++) { if (numbers.IndexOf(characters[i]) < 0) { parameter = Properties.Resources.textSendMail; message = Properties.Resources.textSendMailNotValid; this.TraceOutput(string.Concat("\n\n\n", message, "\n\n\n")); return false; } } return true; }Oh, it just goes character by character to verify whether or not this is made up of only digits. Which, by the way, means the CLI argument needs to be an integer, and only when that integer is 1 do we send emails. It's a boolean, but worse.
Let's assume, however, that passing numbers is required by the specification. Still, Markus has thoughts:
Handling this command line argument might seem obvious enough. I'd probably do something along the lines of "if (arg == "1") { sendMail = true } else if (arg != "0") { tell the user they're an idiot }. Of course, I'm not a professional programmer, so my solution is way too simple as the attached piece of code will show you.
There are better ways to do it, Markus, but as you've shown us, there are definitely worse ways.
.comment { border: none; } [Advertisement] Plan Your .NET 9 Migration with ConfidenceYour journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Goldman Sachs: Why AI Spending Is Not Boosting GDP
Read more of this story at Slashdot.
Xen Project delivers solid hypervisor update and keeps working on RISC-V port
The Xen Project has delivered an update to its flagship hypervisor.…