Sunday, December 03, 2006

The Inter - face

Interfaces in object oriented programming have been around for a few years now. I still run into people who do not use interfaces while programming.
For .net developers this might be because VS.NET does not have a menu for adding interfaces, and VS.Net allows you to be more or less ignorant towards the structure of the program you are making (Drag'n'Drop coding I think I would call it :)).

To me structure is the most important thing in software development. Interfaces is a cornerstone in building this structure.

Interfaces are great when you need to consume objects, and you are more conserned with its use than what it is.
Interfaces come into play when you want to create reusable code. Directly copying source code is not a good solution and I prefer structuring my way out of it. Making a component or a framework if you like.
If you can avoid it keep your reusable components working without the user having to extend a series of classes of yours. The user might have reasons not to extend your classes, such as the need to extend other classes. Maybe the objects need to be serialized in between calls or some thing else. If you force the user to extend your classes, you must be sure the user can do anything to it in another context.

There is of course nothing wrong with providing a default implementation for your interfaces. Please don't give these default implementation the name that fits the use of the interface. IList and List is a bad example of naming a default implementation, or maybe it's more that IList should not have a default implementation. Because of these bad names, I dislike prefixing interfaces with I. The interface is the main thing and should be given the real name. Normally there is no need for a default implementation, but if needed I like giving the default implementation a Impl postfix far better.

When you design your system, you must think interfaces to begin with. There is little benefit from designing a system using classes, adding interfaces to all classes afterwards. Interfaces are only relevant if they actually respresent some decoupling in your system.

As a class can implement as many interfaces as you like, interfaces can be very small. This means that by using interfaces you code will only require the functionality it actually uses.. and the people using your product will only have to implement what is needed. They do not have to extend an existing class and thereby enherit a lot of useless functionality.

Less is more!
Interface > Class

Sunday, November 26, 2006

Unit test addicted

I have become addicted to unit testing. So far I haven't noticed any side effects :)

Enough small talk... This is why I like unit testing so much:
  • It forces me to initially focus on functionality.
  • It lets me refactor central code bits and see if any dependant projects break because of it.
    I have worked on projects where nobody wanted to change stored procedures on the database. Instead new stored procedures were created. Thereby not breaking existing code.
  • It lets me open up old projects that i don't remember anything about and experiment when fixing an error. It more or less functions as a description and validation of what the application does.
  • It feels good when delivering a product knowing that it actually does what you expect of it.

Monday, August 28, 2006

A use for operator overloading.

Generally I think the main purpose of operator overloading is to conceal what your program does (unless dealing with types similar to primitive types), and this is the first time I have really found it very useful. My adwise is therefore: Don't try this at home, kids ! :)

For the last year I have been working on and off on a framework that should interface an existing product. The interface should be abstract so that it was possible to change the product without the interface of the framework changing. It should of course also be very easy to use.

One of the things I did to make this happen was to make a class structure so that criterias for searching data could be nested (composite pattern) in a tree structure. In this way users can make complex searches and easily combine them into many levels in the tree.

Consider the following example:
FirstName = "Rune" and (LastName != "Petersen" or LastName != "Knudsen") and Age < 32

I want someone called Rune, but not Petersen or Knudsen. The person should be below 32.

This shows the object structure you need to create to be able to perform the search. Although everything is nicely separated from the actual implementation the drawback of this structure is that it takes many lines of code to construct the criteria, and it being multiple levels of objects makes it hard to instantly comprehend when you look at it.

Another not so appealing thing is that small logical changes might course the structure to be very different. For instance if you don't want to and the Age criteria, but or it. Now suddenly there must be 3 levels in the object structure.

FirstName = "Rune" and (LastName != "Petersen" or LastName != "Knudsen") or Age < 32

Results in the following object structure.

This has troubled me, since I generally like the object structure for its extendibility. But then I rediscovered operator overloading.

First I changed the criteria interface to be an abstract class. Although operator overload are static, and explicitly define what classes they act on, in C# they have to be implemented as part of the most general type used. In this case criteria. So therefore no more interface.

I implemented the & and | operator on criteria. This made wonders to usability. When I have defined my simple criterias, I can now define my whole object structure on one single line.

FirstNameCriteria & (LastNameCriteria1 | LastNameCriteria2) & AgeCriteria

Not only is it easier to overlook the whole structure, it is also much easier to change it. All it takes to generate the second structure is changing a character.

FirstNameCriteria & (LastNameCriteria1 | LastNameCriteria2) | AgeCriteria

To make it even easier to read I also overloaded the compare operators on the Fields. This only deals with the simple criterias, but the rest will have to be dealt with later. having overloaded operators on the Field, the criterias can be created like this:

FirstName == "Rune" & ( LastName != "Petersen" | LastName != "Knudsen" ) & Age < 32

What remains for me is to find a way to document this functionality. As intellisense and documentation written for each overload doesn't show, my concern is that nobody will ever use this (and thereby not save a lot of time).

Tuesday, July 18, 2006

Success is relative.

I have found out that the success of a project is relative to expectations. Some might say that success can be measured in money. This is also true for long term measurements... For short term money is a bad unit for measuring success. Some sales people think that money is the way to create success, which leads to over selling instead of thinking long term success.

I have always thought that sales is the tool, not the goal.. The goal is to deliver something our customers like and would like to have more of. Or put in another way: deliver what the customer expects. The only way to be able to do this is by knowing the customers expectation, and at an early stage adjust them if we can't deliver what they expect.

Monday, July 17, 2006

VS.Net is for Mort

I have read the blog of Scott Bellware about the issue of MS targeting development applications towards the Mort personallity of their user stereotype. (Mort is the: don't think, just implement type). I came up with some thoughts.

It doesn't come as a surprise to me that this is what they are doing with their development tools. To me dotnet has always been the point and shoot version of Java. They have added some syntaxes that don't add any functionality, and they have removed some so that the developer is not bothered by the compiler when using exceptions (for me personally I would rather have exceptions syntax errors caught compile time than runtime).

VS.Net is not a bad tool, but it is not directed towards my needs. I like to focus on structure and maintainability. I like to be in control because thats the only way I can be creative.

VS.Net is like a DSL for programmers that are not too sure of them selfes. In 10 minuttes you can create a brand new application using technologies you never heard of before. You probably won't know what is going on in the program, and you will have a hard time maintaining it. Perfect for the Mort type :)

I have been concerned with making a standard product extendable, and to this VS.Net could be great. I though of creating a DSL so that the programmer doesn't actually have to focus on what is happening, but just drag a few boxes together and thereby extending the product. But if functionality is served like this, is there any need for a developer? Wouldn't a Mort like sales person be sufficient?

For me there is no real alternatives for programming .Net. I have only tried CSharpdeveloper which seems great. But it doesn't support ASP.Net :( Until ASP.Net and Windows.Forms is opened up like the CLR and C#, the open source community will have a hard time keeping up with MS changes in technologies (I still haven't found any technical reason to why they changed compilation completely in 2.0).

What I like about Eclipse is that it helps me do what I need. Refactoring is a essensial part of working in eclipse. I'm never suprised while working in eclipse... It doesn't copy things around. I'm always aware of what classes I'm using.

Friday, March 17, 2006

Using tools that are too complex

For the last couple of days I have become very frustrated by using VS.Net on a project. Because of this I have developed a new strategy for what tools I use. If the tool I'm using does stuff I don't understand or control I need a simpler system to fall back on.

My problem was related to using some com components. Everything worked fine until I published the project. Then some of my dll's were exchanged with other versions that did not work. I hadn't tried MSBuild yet and NAnt didn't support .Net 2.0 (well, without getting a nightly build). I was stuck with VS.Net :( I finally got it working, but without understanding why...

I will have to try and see if Sharpdevelop is anything worth for.Net 2.0 and I will have to update my version of NAnt.

If a program does "magic" stuff, it's to complex and will probably do stuff you don't want from time to time.

Thursday, February 23, 2006

The kind of software I would like to develop.

Some time ago I visited my brother in law. He had just started playing a game on the internet, and in fact he wanted to play this game every day and every night.

When I decided that I wanted to develop software for a living, it was because I realized that only my imagination would limit my creativity. I have realized that customers also limit my creativity.
It seems that the number one feature of a computer game is that it has to bee cool, which means anything goes as long as its cool(and doesn't cost money). This is less contraining limitation than I'm used to by the business rules that normally define the boundaries of my work.
The computer game has another great feature. The users are only entertained and some use most of their spare time playing the game. Life is short, and to have people waste their spare time on a program I'm part of, is to me the greatest acknowledgement.

Actually... Mostly I was just inspired by the gratitude of the users of games. Enterprise application development is not bad either :)
The easiest operating system I have tried yet.

I tried to install Linux some years ago. I gave up using it as my primary operating system as I thought I had to use too much time setting it up.
Things have changed and Ubuntu is an example of an operating system that requires almost no setup. It installs with a collection of applications that will satisfy most desktop users.

For instance if you want to install mono on your system so that you can run .Net application you do the following.

sudo apt-get install mono

  1. "sudo" changes the user to be the administrator.
  2. "apt-get" is the package manager.
  3. "install" is the action you want with the package.
  4. "mono" is the name of the package.

Now all you have to do is follow the instructions on the screen. You will be prompted for the administrator password, and asked whether you want to install all the dependent packages. It doesn't get much easier than that.
Next I want a development environment :

sudo apt-get install monodevelop

Actually I could have started with this command. Monodevelop is dependent of mono, and it would have installed mono automatically.

Once a program is installed this way, you will be notified if the packages has new versions.

Wednesday, February 15, 2006

Avoid using the System.Collections namespace.

It is good practice to avoid the use of variables of type object*. By using object as a data type, you will not have compile time validation on your types, and you have to cast you objects every time you use them. Its the exact same situation when using the System.Collections namespace. Objects handled by System.Collections will only be validated to the object type at compile time. It compares to creating an object[] array to contain strings. You would never do that. You would create a string[] array.

The System.Collections namespace has served us well in the past, but now it is time to move on.
Use System.Collections.Generics instead!

*(sorry for the casing, but I think I have already written about my opinion about diverting the .Net languages so that the same classes are called different things in different languages)

Sunday, February 12, 2006

Playing a bit around with the .Net 2.0 framework.

Generics in .Net works nicely. Its nice to see casting and custom validation can be removed from one's code.

I have written about my problem with the naming convention of interfaces in .Net and now I'm going to write a bit more about it. In the System.Collections.Generics namespace, they have renamed a class compared to the old Collections namespace.

The ArrayList is now... TADA! List ???

I'll give you an example of why I think this is a bad name.
IList list = new List();

You want a list. So you create a variable of the type IList. Now you want an instance. But List doesn't make sense as a class name. It doesn't tell the user anything about it's behavior. Does it work like a linked list, an arraylist or maybe an array? You can't tell by the name.
ICar car = new Car();

This example is thought up, but equally weird.
customer: Hello! I would like to buy an ICar.
dealer: and which type would you like?
customer: I would like the Car...

Car car = new Porche911(); makes more sense just like List list = new ArrayList();

To me this looks like a lack of understanding of interfaces. It however makes perfectly sense in the VB6 world where interfaces don't exist:
List list = new List();

At work we have decided to drop the use of I. :)

Tuesday, January 10, 2006

The smartest things are often the most obvious.

Behind the scene, my blog is flooding with posts in draft. I don't have time to publish the posts the way I want (without too many spelling mistakes etc.). The reason for this is that everywhere I look I see things to write about. I think the reason for this is that smart things are often obvious when you have been introduced to it. There is nothing like the "Ahh!" experience when someone explains something to you, you understand instantly. I think this goes for software as well as for everything else.

The wheel is one of the best inventions ever: it has a clear advantage, and everybody understands it as obvious. This is what I want! I want to design applications with the same characteristics as the wheel. Very useful, and comprehendible for everyone.

This leads to my problem with this blog. I could start writing about the wheel as one of the mayor components of modern life, but my guess is that all humans alive already know about the wheel. I'll instead focus on software development, but it is unavoidable to write about the obvious. The obvious is often the best... I'll try my best to make it interesting :)