Saturday, July 18, 2015

good habits!

I saw David McCarter speak at the Austin .NET User group on Monday night on good coding practices. He suggested that by the time a bug exists in code that was not proactively prevented in the design phase it takes ten times as long to chase it away as it would have if it were curtailed upfront. In production it takes one hundred times as long, and both of these figures should encourage (scare) you to not be sloppy. He went through his own grocery list of to-dos and I took notes. Things said:

  • Portable Class Libraries seems to be the proper name for what David was referring to when he suggested that most code should be in portable .dlls. This is a new (well, newish) Visual Studio project type (and, yes, you have to start with it to begin with as you can't cast existing projects to this) which allows you to specify what platforms you will deploy the code to (Windows, Xbox, Windows Phone, Silverlight) and then restrains by way of the complier what C# it will allow so that you don't write something that can't roll out to all targeted environments.
  • Inheritance, polymorphism, and encapsulation are the three pillars of object-oriented programming. You should really use them.
  • What's the biggest performance issue in modern apps? The internet itself! Its speed and intermittent availability poses some challenges. Caching data (cache long running reports) and having a policy of "less data transfer" helps (make calls chunky not chatty and only go across the wire when you have to), but in today's world all applications should be architected for being occasional connected to the internet. Think of how Microsoft Outlook lets you send an email even as you sit on an airplane cut off from everything. It just goes to that "Outbox" queuing grounds, right? Brilliant! Why can't posts to Facebook behave like that? Duh. Azure Mobile Services has a solution in this regard and there is a new version of the Microsoft Sync Framework for Windows phone (and also Apple/Android) called SQLite which gives you a dumbed-down (no stored procedures!) MSSQL database which will automatically sync up to the real MSSQL database when it comes online, so that you may just read/write to SQLite! In the absence of sprocs I guess one has to use an ORM or write old school PHP-era select statements in the code itself as was the norm a dozen years ago. You can ship products without a client database and SQLite will just build the first time it is run. This sounds like what I hoped code-first Entity Framework would be like, but I've been burned before so I'm skeptical.
  • He had a slide titled "Perception is Everything!" with copy reading "To ensure your users are happy make sure to work on the perceived speed of the app" and a chart giving a breakdown of what the user perceptions will be at various degrees of lag/delay as measured in milliseconds:
    0- 100 Instant
    100- 300 Small perceptible delay
    300- 1,000 Machine is working
      1,000+ Likely mental context switch
      10,000+  Task is abandoned
    Even in a WinForms application you do not want to make users wait ten seconds. Amazon does not run your credit card when you checkout at its store. It does that later, speeding up the perceived-first-hand process, and then flags you if something went wonky.
  • IntelliTest in Visual Studio 2015 will write unit tests for you. You may click on a method, specify IntelliTest to do its thing, and produce. What does cyclomatic complexity mean? It's a measure of complexity based on the number of possible paths through code. In writing unit tests you should ideally cover all of them. Do you really want to write 700 tests?
  • .dlls should be dumb and stupid. They should not log exceptions or send emails. They should trigger events to hand up to other things to do this.
  • Use .NET Trace Listeners to log exceptions and inner exceptions. Log as much as you can and make sure that you log in a way that is not opaque so that one may actually reverse engineer what happened from the log instead of being left in the dark.
  • Use strong-named assemblies. This prevents someone from hacking into your server, grabbing that .dll named CreditCardProcessor.dll, using JetBrains dotPeek to cast the CLR inside back to C#, putting sinister code inside the pulled out stuff to forward credit card information on to elsewhere, and then recompiling the .dll and replacing it at your server by way of obfuscating the CLR code so that will only make sense if you have the appropriate digital signature.
  • Globalization and localization should be embraced upfront. Some of David's canned C# code for as much looks like so:
       string birthDate = p1.BirthDate.ToString(CultureInfo.CurrentCulture);
       string annualIncome =
             p1.AnnualIncome.ToString(CultureInfo.CurrentCulture);
       string info = string.Format(CultureInfo.CurrentUICulture,
             Properties.Resources.UserInfoFormat, p1.FirstName, birthDate,
             annualIncome);

    Above, "User Info For {0} Born On: {1} Annual Income: {2}." or something like it is going to be at the lookup against UserInfoFormat as the value at the English language resource. Pretty straightforward stuff, huh? A little more new to me was his internationalization friendly way of comparing objects in sorting them:
       public static int ComparePerson(Person p1, Person p2)
       {
          return string.Compare(p1.FirstName, p2.FirstName,
                StringComparison.OrdinalIgnoreCase);
       }

    He said that FxCop was a good tool to use for catching globalization/localization gremlins and that CodeIt.Right by submain will clean up bad code for you in this regard.
  • Julie Lerman is the queen of Entity Framework!

No comments:

Post a Comment