Showing posts with label fail-at-once. Show all posts
Showing posts with label fail-at-once. Show all posts

2010-01-06

Catch property, field and method name changes compile time in dotnet

When you want to populate a dropdown listbox with customers

class Customer
{
int Id;
string Name;
...
}
and have to write

myDropdownListbox.DisplayMember = "Name";
myDropdownListbox.DataMember = "Id";
or

myGridColumnCustomerName.DatatMeber = "Name";
you really get a sour taste in your mouth.

Having magic strings like above spread in your code is really bad since it always compiles but might fail runtime. This means more manual tests. Which in turns means a certain friction against renaming properties while refactoring.
I have been in way too many projects where one table has a field ItemNumber when it should have been ItemCount and where some fields are called Nr while another Number and these names are spread up in the layers to reach the presentation layer where they surface as magic strings like the examples above.

Luckily there is a solution in Dotnet 3 with LINQ. It isn't the prettiest but it fails compile time when it should and that is considered a good thing.

( I won't bother with explanation - just read the code. )

// The Code.
class ReflectionUtility
{

public static string GetPropertyName<T,TReturn>(Expression<Func<T,TReturn>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name;
}

public static string GetMethodName<T,TReturn>(Expression<Func<T,TReturn>> expression)
{
var body = expression.Body as UnaryExpression;
var operand = body.Operand as MethodCallExpression;
var argument = operand.Arguments[2] as ConstantExpression;
var methodInfo = argument.Value as System.Reflection.MethodInfo;

return methodInfo.Name;
}

}

// The test code.
class MyClass
{
public int MyField;
public int MyPublicProperty { get; set; }
public string MyReadonlyProperty { get { return string.Empty; } }
public int MyMethod() { return 0; }

private MyClass() { } // To make sure the class doesn't need a default constructor.
}

class Program
{
static void Main(string[] args)
{
string fieldName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyField);
Console.WriteLine(string.Format("MyClass.MyField:{0}", fieldName));
Debug.Assert("MyField" == fieldName);

string propertyName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyPublicProperty);
Console.WriteLine(string.Format("MyClass.MyPublicProperty:{0}", propertyName));
Debug.Assert("MyPublicProperty" == propertyName);

propertyName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyReadonlyProperty);
Console.WriteLine(string.Format("MyClass.MyReadonlyProperty :{0}", propertyName));
Debug.Assert("MyReadonlyProperty" == propertyName);

string methodName = ReflectionUtility.GetMethodName<MyClass, Func<int>>((MyClass x) => x.MyMethod);
Console.Write(string.Format("MyClass.MyMethod:{0}", methodName));
Debug.Assert( "MyMethod" == methodName);

Console.Write(Environment.NewLine + "Press any key.");
Console.ReadKey();
}

}
Honor those who should.

Update: When copy-pasting through manoli.net some angle brackets got dropped. This is, hopefully, fixed now.  Otherwise - get the source here: http://selfelected.pastebin.com/f77563a02

2008-07-03

Defensive programming and Fail at once

There is something called defensive programming http://en.wikipedia.org/wiki/Defensive_programming that is supposedly something good. I believe so too but it might have a way of hiding bugs.

In defensive programming you recieve data and inspect it for flaws. When it is possible you manipulate the data so it is correct and usable again. This is good so as much your code works.

But when you are in a project where your code is just a cog in a bigger machinery this approach is not necessarily the best; by recieving and hiding flawed data a bug somewhere else is hidden.

In the example in Wikipedia a string limited to 1000 characters is manipulated. The suggested solution is to truncate the string and keep rowing as if there wasn't a leak in the first place. Depending on the circumstances the bug might be at the caller and by removing the very bug instead of the symptoms the very problem disappears.

According to Fail at once an error should surface as soon and close to the source as possible. The chances for data resulting of the bug to propagate, is then smaller and the bug tracking is probably faster.

In the example it would have been better to throw an exception than to just keep on with data, now faulty in another way than to start with.

Or like this: if a user writes an essay of 2000 characters he probably wants to know that it cannot be saved the very moment ctrl-S is pressed instead of 2 days later when proof reading, when the last 1000 characters are gone both from mind and binary space. Or an operator of a tube bending machine prefers to know if his machine is faulty when he is working at it instead of two weeks later when the tubes are buried inside a wall somewhere.

2008-06-29

Fail at once – an explanation

I have written 2 articles tagged as Fail at once without explaining what the filosophy behind the name is. Shame on me.

It is an old truth that the earlier a bug is found the cheaper it is to fix.
Automated tests tests things that can go wrong; but what if those things couldn't even go wrong in the first place?
Code that won't compile won't make it into production. Ever.

It is cheapest to not write any errors at all.

Today Fail at once does two things: It stops compiling when it notices something is wrong and at all other times it tries to help the programmer do the right thing.
Typical example of the first is to always use type safe variables and the latter to name things in such a way that there is one very natural way to write the code. By using this explicitly and intelligently you get a leverage for writing better code faster.

2008-06-18

Make sure your objects are fully populated – Fail At Once

The default constructor
public Customer()
{
}

is seldom needed while working with business objects. Honestly – how do you need an object that is not? Do you have a Customer or do you not? A few situations comes to mind where an almost-Customer is needed but they all smell of refactoring, i.e. base class, sub class and two constructors.

To make sure I don't have an object that is not fully populated I make sure the default constructor is not reachable. Either through creating other constructors or by making it private the times it is needed internally. Instead I create a constructor that takes all necessary parameters to fully populate itself. If there are variants I create more constructors. I am not afraid of writing code but I strongly dislike putting bugs into production. Hence Fail At Once.

Sometimes it is handy to have a void method taking all parameters and calling it from the constructor but this is just a variant of the pattern above that objects that are not correctly populated are very seldom useful.

Another advantage with this routine is when adding (or removing) another mandatory field. Then there is one and only one place to update to make the compiler give you all places to update.

I have noticed that it is hard to make handy lists without having a default constructor but this, I presume, is just the exception that confirms the rule.

Bugs that can't compile will not go into production.

2008-06-16

Do not type cast – Fail At Once

Avoid casting types.

Why do I write about this? What has it do do with quality and projects and architecture? Well... each thing that cannot break doesn't have to be tested and... cannot break. Less testing, less coding, less bugs.

When working with class libraries that are dependant on the generic type one cannot avoid type casting fully. The solution then is to encapsulate and wrap the cast through inheritance or composition.

If you wrap your type cast you have 1 test case instead of a test case per call.

What about datagrids and combo boxes that have an internal Rows or Items collection or Tag attribute? How can they become type safe without having to rewrite the whole control? Unfortunately I don't have a perfect solution but as I have seen the evil in type casts I avoid them and instead of writing test cases and tests I spend some time looking for a type safe alternative. These are typically called row.OrderTag or combobox.CustomerItems. Overriding the method or attribute is not possible since one cannot change type; but one can override and set the [Obsolete] attribute to at least get a warning. Pepper this with a Debug.Fail( ”Please use the OrderTag property instead.” ) and things will stop in any test case that runs it. Many times one can even set the compiler to fail with [Obsolete(true)] to be totally sure the call is never made.

Another problem then is when two different types really are returned. Well... write two methods then. Even overload them; as long as the compiler understands your goal.

Final thought: How should one get this type of thinking into the spine of a project? It is not something that can be ordered but has to be understood and taken to heart by the involved. If someone has an idea please drop me a line; but until then being a good example is a good beginning.


2008-06-10

Fail At Once

What if you didn't have to test your application?

What if you worked together with tools to make sure some bugs never even left the compiler? That would be less to test; faster development cycle and more stable code.

In search of better name I call this Fail At Once.

I will get back on the subject.