Friday, February 25, 2011

Testable C# or C# TUFs and TUCs


Re-reading Michael Feathers nice article on "Testable Java" I decided to see how the same thing looks in C#. Now, Java and C# aren't too far a part, so the difference isn't huge.

The "Testable Java" article gives a simple rule for how we can write code that is friendly to unit tests. -As the article points out the rule is superflous if we follow TDD stricly. But - being human - we don't always do that. Sometimes we write only integration tests or even acceptance tests here and now, and postposne unit tests. Sometimes we skip the automated tests altogether. In these cases it's an advantage to have code that is at least friendly to unit tests. If so, it's afordable to add the unit tests later.

Feathers' rule is:
"Never hide a TUF within a TUC"
and Feathers goes on to define TUF as a "Test Unfriendly Feature" and TUC as a "Test Unfriendly Construct". Now TUFs are things that we want to mock out in many unit tests, but TUCs are language constructs that are hard to substitute for testing.

TUFs

Examles, from the article,  of TUFs:

  •   Database access
  •   File system access
  •   Network access
  •   Access to side effecting APIs
  •   Long running computations
  •   Inscrutable computations
  •   Static variable usage

The first three are basically I/O, and in general I/O is test unfriendly because it is slow, and usually assumes things about the outside world - like "the webservice is reachable" or "the robot arm is connected through the serial port".
The next - side effects - is about avoiding tests that changes something and annoys somebody.
Long running computations are a nuisance, and will make you skip test runs.
Inscrutable computations, are things that are just plain hard to understand - maybe due the "clever" code-smell or to essential complexity.
These TUFs are all TUFs in .NET as well.

TUCs

The article lists a number of Java TUCs. This is my ported list of C# TUCs:

  • Sealed classes
  • Static methods
  • Private methods
  • Static initializers
  • Constructors
  • Static constructors 
  • New expressions

 and these are few more C# TUCs IMHO:

  • Non-virtual methods
  • Internal methods
  • Internal classes  

The point is to remember - even when you skip the TDD strictness - that testability is an important part of maintainability. So if maintainability is quality attribute you want, then keep an eye on the testability. If not, those TUFs inside of TUCs will come back and bite you.

Oh, and the other point: Go read Michael Feathers' article. It's well worth it.

Thursday, February 3, 2011

Random Thoughts on Tiobe Index January 2011


The Tiobe index is an index of the popularity of programming languages (formally defined here).
According to the Tiobe web site "the index can be used to check whether your programming skills are still up to date or to make a strategic decision about what programming language should be adopted when starting to build a new software system."

Some Data to Notice From the Index

As someone who has worked mainly in .NET through the last several years, my interest in the index focuses on .NET languages (and on my favorite language for recreational coding for some time now: Scala). The rankings of .NET languages in the January 2011 index are:
  • F# ranked between 50 and 100 (the index put these 50 in one big pile because differences the in scores are minuscule)
  • VB.NET at no. 49
  • PowerShell at no. 28
  • C# at no. 6

For perspective here are some selected other languages:

  • BETA ranked between 50 and 100
  • AWK at no. 31
  • T-SQL at no. 17
  • Ruby at no. 10
  • VB at no. 7
  • Python at no. 5

And also worth noticing is that Java, C and C++ take the top 3 spots, and have for a decade.

What I Get From That Data

Now what does this mean for a .NET developer?

  1. C# is hugely popular, but still much, much less popular than Java. Looking at the long term trend C# is steadlily gaining ground. So having and maintaining C# skills is a really good idea in terms of making a living.
  2. VB.NET is so unpopular it's almost off the charts...in a bad way. But (!) considering how the Tiobe index is done I don't think it distinguishes VB and VB.NET properly. So IMHO it's more fair to add the VB and VB.NET scores which would place VB.NET at 5th place - where VB is now. If this is true having VB.NET skills is a really good idea too, but the long term VB.NET trend is downwards, especially over the last couple of years. So maybe it's time to translate those VB.NET chops to C# chops?
  3. F# doesn't seem to be going anywhere. So don't learn F# for job security. Learn it to open your mind. But then again, if you want to open up your mind, and you're a .NET dev, why not look outside .NET and do Scala or Clojure or Erlang or something completly left field?
  4. PowerShell seems to be becoming important. Maybe it's time to really learn it.
 What does it mean for the .NET community?

  1. Assuming the VB and VB.NET points needs to be added C# and VB.NET combined would weigh in at a 3rd place, meaning that .NET is doing very, very well in terms of popularity. 
  2. Both Ruby and Python are doing very well. So if the Iron* languages are dropped an opportunity for engaging two very large communities is lost. That would be really sad!

Those were my 2 cents. Go check the index out, and make up your own mind. And let me know what you think :-)



Oh, and Scala is at place 50, just within the list proper. Still rooting for it :-)

Thursday, January 13, 2011

Doing DCI with ASP.NET MVC

The DCI - Data, Context, Interaction - paradigm (intro article, an earlier post) brings the roles domain objects play at runtime to center stage. DCI also fits right into the gaps of MVC. What? Which gaps?

MVC Gaps
Back in the day, when MVC was originally described by Trygve Reenskaug as an architecture approach it was all about the users mental model, giving the user the sense of just working directly with the domain objects. Now dont confuse this with the dreaded CRUDy forms-over-data battleship grey enterprise app. Those apps force the user to manipulate the data directly; respecting, fighting and being forced into submission by the techniocal details of databases. MVC on the other hands puts that the model is the users mental model - the programmer, then has to deal with hiding the technicalities of persistence and such. As illustrated below the users works as if manipulating the domain objects directly. The view simply reflects the model state, the controller reacts to user actions, and translates them to model updates, and that's it.
Direct manipulation metphor as illustrated by Trygve Reenskaug
This is fantastic for fairly simple apps. But as soon we introduce business rules with a certain amount of complexity, the direct manipulation metaphor does not suffice anymore. We need somewhere to put those business rules.  -The controller already has clear responsibility, so in keeping with single responsibility principle that's not the place for the behaviour. -The traditional OO answer is to put the behaviour into the model, but that leads to hard-to-follow logic jumping back and forth in the model objects, and (gark) up and down long inheritance chains. Moreover it turns out that a given domain object will play different roles over times. I.e. the object doesn't need just one behaviour, it needs several, and even worse it needs different behaviours over time. There goes SRP again, only this time in the "intelligent model".

Roles and  Contexts to Fill the Gap
So we need something more than MVC: The view is not the place for the behaviour, the model is not the place for the bahivour, and the controller is not the place for it either. This is where roles as separate things come into play. We want explicit roles. We want those business rules implemented in the roles. And we want to assing those roles to domain objects as needed.

The role a given object plays at a given moment depends on the context at that moment. So why not introduce contexts as something explict along with the explicit roles? Together roles implementing behaviour and contexts assigning roles to objects fill the gap in MVC.

Back to APS.NET MVC
Lets get practical: Where do the contexts and the roles go then? Since the contexts manage assigning roles and kicking off the behaviuour the contexts and roles fit well together. In the ASP.NET MVC + DCI demo I did for ANUG I organized the code like this:

 The Contexts folder has a subfolder for the use case I demoed. Other use cases would have their own subfolders. Inside the subfolder is the context for executing that use case, and the associated roles.

What is a role in C#? A role in C# is a set of extension methods on an interface (see this and that for more on roles in C#):

    1     public static class TransferMoneySourceTrait
    2     {
    3         public static void TransferTo(this TransferMoneySource self, TransferMoneySink recipient, decimal amount)
    4         {
    5             // The implementation of the use case
    6             if (self.Balance < amount)
    7             {
    8                 throw new ApplicationException(
    9                     "insufficient funds");
   10             }
   11 
   12             self.Withdraw(amount);
   13             self.Log("Withdrawing " + amount);
   14             recipient.Deposit(amount);
   15             recipient.Log("Depositing " + amount);
   16         }
   17     }

How does the context track the role assignments? Simple:

    8     public class TransferMoneyContext
    9     {
   10         public TransferMoneySource Source { get; private set; }
   11         public TransferMoneySink Sink { get; private set; }
   12         public decimal Amount { get; private set; }
   13 
   14         public TransferMoneyContext(TransferMoneySource source, TransferMoneySink sink, decimal amount)
   15         {
   16             Source = source;
   17             Sink = sink;
   18             Amount = amount;
   19         }
   20 
   21         public void Execute()
   22         {
   23             Source.TransferTo(Sink, Amount);
   24         }
   25     }
   26 

Where are the objects mapped to roles? Right in the seam between the controller and the context (lines 35 to 37):

   11     public class TransferMoneyController : Controller
   12     {
   13         AccountRepository accountRepo = new AccountRepository();
   14 
   15         public ActionResult Index()
   16         {
   17 
   18             ViewData["SourceAccounts"] =
   19                 accountRepo.Accounts.Select(a => new SelectListItem {Text = a.Name, Value = a.Id.ToString()});
   20             ViewData["DestinationAccounts"] =
   21                 accountRepo.Accounts.Select(a => new SelectListItem {Text = a.Name, Value = a.Id.ToString()});
   22             return View();
   23         }
   24 
   25         [AcceptVerbs(HttpVerbs.Post)]
   26         public ActionResult Index(FormCollection form)
   27         {
   28             var sourceAccountId = form["SourceAccounts"];
   29             var destinationAccountId = form["DestinationAccounts"];
   30             var amount = form["Amount"];
   31 
   32             var sourceAccount = accountRepo.GetById(int.Parse(sourceAccountId));
   33             var destinationAccount = accountRepo.GetById(int.Parse(destinationAccountId));
   34 
   35             new TransferMoneyContext(sourceAccount as TransferMoneySource,
   36                 destinationAccount as TransferMoneySink,
   37                 decimal.Parse(amount)).Execute();
   38 
   39             ViewData["Amount"] = amount;
   40             ViewData["Source"] = sourceAccount.Name;
   41             ViewData["Destination"] = destinationAccount.Name;
   42 
   43             return View("Result");
   44         }
   45     }

Apart from lines 35 to 37 this is all just standard ASP.NET MVC stuff: Getting data in and out of the ViewData, and returning the view to render back to the user.

Summing Up
MVC is great for simple situations. It doesn't quite scale to complex business scenarios, but DCI does, and the two are a great match.
Leveraging the power of C# to do DCI and the niceness of ASP.NET MVC to go along with it, makes for a - IMHO -very compelling architecte style for an enterprisy web app.