On Readability
Which of these two statements is more readable?
Assert.AreEqual(5, result);
Assert.That(5, Is.EqualTo(result));
And which one is read faster?
4 commentsDoes C# becaming old?
This year I was at the NDC2010, one of the best conference that I have ever see for the quality of the sessions and for the speakers.
I follow some speeches and discussions about Ruby/IronRuby (Scott Bellware and Shay Friedman) that took me to think about the state of C# and the compiled language in general.
C# is without doubt a wonderful language, as soon as I start to work with it in 2001 I loved its severity and its elegance. I always loved the non virtual methods by default, the sealed keyword and other constructs that protect my code to an improper use.
Then I discovered Ruby (well…I discovered Ruby some years ago but only in the last months I start to work with it seriously).
Ruby is simple, without many constraints and its dynamic nature leave lot of power to the developer since that he can loose control if he’s not quite expert.
Learning Ruby make me change some opinion about C# that compared with it is more “ceremonious” and plaster.
In addition the constructs that I said before (non virtual, sealed …) by another point of view make our classes hard to test (take a look a the Michael Feather session about language testability).
Most people thinks that C# is more safety than Ruby because the compiler, the type system, the intellisense and so on, help us in committing less errors, but, given that we are professional developer, do we really need them? Don’t you think that they limit our productivity?
The new versions of C# go in the direction of dynamic languages, but perhaps its roots can’t give real freedom like other languages. It’s time to take a look around?
2 commentsWindsor Container and NHibernate sessions
When developing MVVM WPF applications that use NHibernate as ORM one of the problems that you encounter is how to manage the sessions and keep the application fully testable.
I like using a Session per “screen” that in the MVVM world is equivalent to use “one Session per ViewModel”.
I also like to separate the presentation logic from the rest so I also create a Model for each ViewModel (even if this is not strictly necessary)
Finally the Model use one or more repository to access the database.
So, the NHibernate session is tied to the life of the Model and all the repositories that belongs the same model should share the same session so I can build transaction between repositories.
In addition to this I would like to inject the interfaces of the dependencies: the ViewModel will get the IModel, and the Model will get the IRepository1, IRepository2.
This picture should clarify the complete schema:
To create this scenario I choose Castle Windsor as a container and with the help of German Shuager, I defined this particular registration method:
public static void RegisterSharedWithFactory<TService>(Function<TService> factory) { _kernel.AddFacility<FactorySupportFacility>() .Register(Component.For<TService>() .UsingFactoryMethod(factory) .LifeStyle.Custom<ResolutionContextLifestyleManager>()); }
This method registers a component using a Factory method to create the instance since we cannot create an instance of the ISession but we must use a SessionFactory. Then sets the the lifestyle to a custom ResolutionContextLifestyleManager to be sure that in the same context the dependencies are created only once.
The implementation of ResolutionContextLifestyleManager is written by German and can be found here.
To understand what it does, consider this test:
[Fact] public void Two_Repo_In_The_Same_Model_Should_Have_Same_Session() { Container.Initialize(); Container.RegisterSharedWithFactory<ISession>(() => SessionHelper.OpenSession()); Container.Register<IRepo1, Repo1>(); Container.Register<IRepo2, Repo2>(); Container.Register<IModel1, Model1>(); IModel1 model1 = Container.Resolve<IModel1>(); Assert.Equal(model1.Repo1.Session, model1.Repo2.Session); // Repo1 and Repo2 shares the same session }
The model uses two repositories that uses the same instance of ISession exactly like in the picture above.
This configuration is very useful to manage the session in the right manner with NHibernate and Castle Windsor container and assure us the testability of all the components.
No commentsRemoving “if”
Often, for example when writing a WPF value converter, we end up with a method like this:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { MyEnum myValue = (MyEnum)value; String imageUri; switch(myValue) { case MyEnum.Value1: imageUri = "..."; break; case MyEnum.Value2: imageUri = "..."; break; case MyEnum.Value3: imageUri = "..."; break; } return new Uri(imageUri , UriKind.Relative); }
This use of the switch statement makes me fill sick due to the fact that the above code is hard to maintain and the complexity raise on every new case.
We all know that we can remove the “if” using the polymorphism, but in this case it’s more simple than that, we can use a dictionary to store the couples enumerator value – imageUri:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { IDictionary<MyEnum, string> dictionary = new Dictionary<MyEnum, string>(); dictionary.Add(MyEnum.Value1, "..."); dictionary.Add(MyEnum.Value2, "..."); dictionary.Add(MyEnum.Value3, "..."); MyEnum myValue= (MyEnum) value; return new Uri(dictionary[myValue] , UriKind.Relative); }
Simple and effective.
PS We could move the construction of the dictionary in a Builder and we also have the option to keep the definitions outside our code (in a resource or in a database) so that we can translate them if needed.
2 commentsAvoid DataGrid*
A lot of software houses are migrating their application to the (new) WPF framework to take advantage of all the new stuff (layout models, controls, templates, styles,…)
WPF leave to the developers the freedom to realize appealing user interfaces that support an alternative interaction model not tied to the old windows controls. The benefits for the end user are countless, more productivity, easier interaction, information “find-ability”, and so on…
But what happens most of the times?
As soon as a new developer opens Visual Studio he asks: “Where’s the DataGrid?”
Why?? Is it possible that the only way that a developer knows to show some data on the screen is to put it in a grid?
I developed a bunch of WPF applications and only in one case I used the DataGrid, I always used ListBoxes, ItemControls, StackPanles….using a template to customize their appearance to show the most important information and to give the user the ability to drill down into the details when needed.
So, please, please, with WPF we have the power in our keyboard don’t use datagrids to show your data, think about your user!
The web is full of examples that don’t use the DataGrid (Google and Amazon for example) so don’t be lazy, take time to design a better user interface!
* No datagrid was used to write this post
No commentsAre we sure that goto is dead?
Last week, during a code review I found this code (I cut some lines to keep the post short)
// [Cut] case USER_AGENT: // [Cut]...various code.... goto default; //we want it to be added to serverVariables case CONTENT_TYPE: // [Cut]...more code (with some "if") goto default; //we want it to be added to serverVariables case USER_LANGUAGE: ParseUserLanguage(variableValue); break; default: ServerVariables.Add(variableName, variableValue); break; // [Cut]...continue...
No words.
3 comments
Working with Legacy Code
I give special attention to code readability and good design when I write programs, these are two metrics that I care about. I like the idea that the team members can read code and understand what the code does.
Today I spent two hours to find a silly bug. I dig with the debugger until the code near the bug, and in that code I have this instruction:
public void Add(String key, MyObject value)
{
if (value == null)
{
Remove(key);
}
else
{
if (ContainsKey(key))
{
this[key] = value;
}
else
{
_base.Add(key, value);
}
}
}
The smell of Copy&Paste
I often read phrases like these “adding a new module to our application is very simple, just copy&paste some code” or “to create a new class you have to copy&paste from an old class”. In my opinion this there is something wrong about this. Copy&Paste is a smell. If you need the Copy&Paste to add some functionality to your application means that you are duplicating your code and then you will be in trouble when you need to maintain it.
What could you do? When the second Copy&Paste happens, stop, read your code, extract a class and “encapsulate what varies“.
No commentsRandom thoughts on TDD
Here it is a flow of random thoughts about Test Driven Development. Naturally IMHO.
- TDD is not about testing application is about design application, and have a (nice) side effect that creates a suite of tests
- The Test obtained with TDD does not cover all the cases, but you can write more test when you need new cases or find a new bug
- The code written in TDD is less and it focused on the needs
- The code written in TDD is more orthogonal and simpler to maintain
- The first red bar is the signal that the test is testing something (and it is very important)
- The tests cannot contains if, switch, etc…so they need to be simple
- Learning TDD is difficult: the impact is the same that you have when passing from structured programming to Object Oriented Programming
- Learning TDD requires times and perseverance
- You cannot learn TDD reading articles and books, you must try it
- Every piece of code is testable
- Testing that the tone of red is that the user likes is not a task of TDD
- With the right use of Mock Objects you can test that the gradient is correctly set
- The test cases comes from the User Stories written with the customer and then they responds to requirements
- The Team that use TDD must be skilled enough…and Pair Programming helps a lot
- The Test code is bigger than the tested code
- TDD force you to think about what you’re writing
- TDD force you to declare what you need before writing something
- TDD put the developer to the client side of his code and so help him to write better interfaces
- TDD helps you to write cleaner and decoupled code
- The Integration Tests helps you to understand how your class interacts with others
- When you need to refactoring your code you can start from tests
- Tests are documentation: read a test is a great help to understand how to use your class
- TDD does not guarantee that you code doesn’t contains bugs
- TDD guarantee that old bug doesn’t come to life again
- The start up cost of TDD is write off during the life of the project
- The TDD reduce a lot the time needed for manual testing
- With TDD the debugger is used like a surgery tool
- TDD helps you to simplify the problem dividing it in small part and every solved part is a small step to the final solution
- Every test case is a single functionality: if one test fail you have only one problem
- If you have two red test you have two distinct problems
- Every test add a new functionality to the code
- Is difficult to test multi threading applications
- It’s expensive testing the UI, but there are patterns that decrease the UI code (MVP/MVC)
- The integrations test against database help you to know if the database and the queries are ok
- TDD force you to written less encapsulated code to make it testable
- TDD force you to write independent object and to inject all the dependencies
- Write test after code is not always possible
- TDD is not a silver bullet (but it’s help a lot!)
TDD as a metodology
TDD is often considered a practice for writing test. It isn’t: TDD is a design practice.
Time ago, while developing an application, it happens that I need to write a resource schedule algorithm. I’m not an expert in schedule algorithms, I read some paper, I know that exists various methods more or less complicated, but the one that I need was quite simple and so I preferred to write it by myself using small steps and TDD that helps me a lot.
I collected the specification from customer, wrote some stories and ordered the stories by complexity, then I begin to write the first test.
The first test try to schedule a single resource always free on a unlimited and free time lap. When this was green I wrote another one with 2 resources, then 3, then N.
Then I wrote other tests that reduced the available time, others that introduce overlapping schedules, to arrive to a test that reproduce real world cases with N resources on N projects with small time available.
What I did is to add a little complexity on every new test and having all the previous green test help me to stay on track and to keep the algorithm right. On every green test I did some refactoring to keep the design clean.
After 2 dozens tests I had the full algorithm ready to use with a suite of test that proved it. I don’t know if this is the best algorithm, I know that it is not the fastest one but I know that it satisfy the customer requirements.
Naturally after the deployment the customer begin to use it and she asked for some modification. If in general this kind on modification on this complicated algorithm is very difficult and dangerous to implement, if you have a suite of test that in a bunch of seconds verify that everything is going right you can write the new requirements quite relaxed adding new tests.
Here the TDD has a double value: first it helped me to resolve a complex problem step-by-step keeping always under control the status of the project, second it helped the introduction of new requirements requested by the customers.
2 comments
RSS


