Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

The art of software development

The subject of software development and how it should be done is always one open for discussions. If there is one thing I've learned over the years as a professional software developer, is that it is nearly impossible to get all developers to agree on this subject. Put 10 of them in a room to discuss software development and you will get at least 10 different meanings. I've always found these discussions interesting, educational and good fun at times, but not always very constructive.

This article is about my thoughts and feelings on software development, architecture and other related stuff. It's purely my feelings on the subject, not my current employer's, and is based on nearly 18 years experience in the business. I'm not pretending that this is the ultimate guideline to software development. But if it makes people think about software development, then I will have reached my goal. At least I got it my chest.

I'm not asking you as a reader to agree with me. I don't have the ultimate wisdom and I still learn, from my co-workers, from the internet and last but not least, my mistakes. I will probably also cut corners here. This document does not cover all angles for each subject. Feel free to comment, I'd love to hear you're comments and ideas. I may have it all wrong, or never learned how to do a proper job.

Use all available resources

Let's start with something pretty obvious: "Anything you can do, someone else will probably have done better". Well, maybe not better, but it is very likely that someone else has dealt with your problem before. Over the last years I found a lot of information, solutions and samples I needed on the internet. Or simply by talking to co-workers. This may seem obvious to you, but I come into situations where developers are struggling for days to solve a particular problem. And more than often, the problem could have been solved in 10 minutes or less, simply by asking the right questions.

Another thing I still don't understand (and hate) is the "not invented here" syndrome. Why is it, that some developers think they're smarter than others? You see people build the strangest things, simply because they don't want to use libraries that are available to them. "No, that algorithm is slow! Just see how it's implemented.". So what if it's slow? Define slow. If it takes 1 second to complete a task using widely available libraries, and .8 seconds to do it using your fully optimized method, do you think a user would actually notice? I'll be honest, if the task has to be performed thousands of times a day; it's probably worth the effort. But in a lot of cases, there's no need.

So make sure you need to create an optimized version before you start. There are plenty of tools to help you benchmark these things. Only then can you really decide to make it yourself. The thing is, widely available libraries work. In fact, they are probably better, safer and will have more features than the one you came up with. One example here would be the use of some VB.Net libraries in C# applications. So maybe they're not as fast as the one you've built yourself. My attitude towards this is very simple. I've blogged about it before when I used the VB.Net IsNumeric method in C# applications. It's been built before; I can use it because it does what I want it to do, why bother building it myself?

Develop and maintain a set of common use code libraries

Over the years, I found that the availability of well-tested code libraries can jump-start the development for a new project. There are so many common tasks that are re-created for each new project. A code library with generic code for these common tasks will make sure you never need to recreate these.

I keep my own set of libraries on a memory-stick. It is being used by other developers in LogicaCmg (my current employer) for various projects. And there are regular updates and additions, by me and by some of my colleagues. The code in my libraries conforms to the following rules:

  1. All code should be generic. It must be possible to add the compiled library to any project and use it.
  2. All code must be properly documented. In the case of my own set of libraries, all C# code is documented using XML comment tags. Whenever I, or one of the other contributors, felt code was not clear enough, comments have been added in the code to better explain what is going on
  3. A help file describing the objects, methods and properties of the code library should exist. For C# code, this can be generated using NDoc based on the XML comment tags in the code.
  4. All code is properly tested. Of course it should be tested. You need to rely on the correctness of the code. If possible, all code should be tested using NUnit or any other form of unit testing. And when updates have been implemented, the code needs to be tested again.

The code library can be a joint effort by all developers in either the team, or your company. When all developers participate in creating such a library, you get the following additional bonuses:

  • Developers will get credits for interesting and/or really useful code, which will increase their commitment.
  • When developers are allowed to participate in building general purpose libraries, then this will increase the acceptance of these libraries.
  • If the libraries are used throughout the company, developers can be more easily exchanged between teams. The libraries used are identical, so it is less likely that whey will need to learn how to use a new set of library code.

Coding standards

When a team of developers start on a new project, the first thing they will need to agree to some form of coding standards. And this is usually the point where discussions already begin. Every single developer has his/her own style of developing software, which can be a good thing. All developers know that the way the develop software is the only road to glory. But when you develop software as a team you need to agree to some basic rules to which all developed code should adhere.

I have a very open attitude towards coding standards. I usually agree to the one the majority wants. I've been in so many projects already, each having their own ultimate coding standard. As long as they contain the following set of rules, I'm happy:

  1. Keep It Simple (KIS) . The more experienced a developer tends to be, the more complex the code he/she creates will be. I always try to avoid writing complex code. But I have to be honest, I don't always succeed. The rule should be that all developers in a team should be able to read, understand, maintain and extend the code developed inside the project. The reason behind this is very simple: Experienced developers are usually the first to leave the project, because they can be used almost everywhere. And especially at the beginning of a new project, their work could prove to be essential to the success of the project. So when they leave, their work needs to be done by less experienced developers. And complex code will then cause problems.
  2. Try keeping your methods as small as possible. I normally try to keep the number of lines for a method/procedure to a maximum of 50 lines. I don't always succeed, but normally that should not be a problem. You might say that doing this is just plain logic. Well, you're probably right. Yet everywhere I go I still see methods that are 200 lines (or more) long. In a few situations I've found methods that were more than 900 lines long. Methods like this are almost impossible to comprehend, let alone maintain or extend. When methods reach this size, they are usually full of flow statements (for...next, while, if...then...else, etc). Splitting these large methods into smaller ones make them easier to test and understand.
  3. Use understandable object, method and variable names. Again, this will probably make sense to most developers. But why do I still run into methods where developers are using ambiguous abbreviations. A method name should always explain what the method will do. I've seen methods being named DoIt. Do what? Variable names should make clear what the meaning of the value inside that variable is. To be honest, I have recently diverted from that rule when I created the EasterSunday method for my ChristianHolidays class. The reason for that was that I could not tell what the variable names should be. But other than that, I normally stick to this rule.
  4. Comment where needed. Comments should explain the code whenever you think others might wonder why the code is as it is. You don't have to explain that values are assigned, or that a loop is being started. If you stick to the above rules, that normally will be clear enough. But you will need to explain why certain checks are being done in the code, if this is not clear for the actual code. And don't over-comment the code. I've been in situations where developers would simply add their name as a comment at the start of some code, and again at the end. Reason: "Then someone else knows I wrote this". Unless you screwed up, no one will be interested.
  5. Write safe code. That obviously makes sense, but somehow developers tend to forget this. Make sure that values fit the variables and casts never truncate significant information. Try to write code that leaves no room for mistakes. For that, have a look at the following (C#) example:
        if (value < 10)
        {
            value = 10;
        }    
    This type of coding is pretty secure. You can see where the if construct starts and ends. When you need to add code inside the if construct, you instantly know where to put it. A lot safer, than this version:
        if (value < 10)
            value = 10;
    When you add code that falls into the same if construct, you need to add the curly braces. When you forget this (and I've seen it happen a lot!) you introduce bugs. Something that is less likely to happen in the first example.
  6. Naming conventions. The mother of all coding standard discussions. My rule: choose one from the list "Hungarian, Pascal case, Camel case" and stick to it. It doesn't matter which you choose, as long as everyone uses the same one. There is, and never will be, one ultimate naming convention, no matter what Microsoft says. They seem to keep changing theirs with the introduction of every new development tool anyway. I've talked to a Microsoft representative some time ago and asked him why Hungarian notation was abandoned. We suggested that as a naming convention for a new project he was reviewing. His answer: "You don't need to know what type of variable it is and where it originates from. You can check using intellisense by hovering a mouse over it!."

There are more rules, obviously. For examples of coding standards, have a look at the following links:

Code inspections

Those that know me, one of my favorite subjects. Setting code standards is one thing. But when no one checks these standards, then there's no use for them. So once you decide to introduce code standards, you should also consider introducing some form of code inspections. In my humble opinion, code inspections should be used to:

  1. Ensure that all developers on the team stick to the code standards. Whether they agree or nor, once code standards have been defined for a project, all members should follow these rules as much as possible. There may be a very valid reason to diverge from the standards, but it should be limited. The only way to make sure people stick to the standards is to check them,
  2. Code inspections can help find problems in the code before they reach the testing phase. I'm not saying they are the answer, but what we all know is that a problem found during development is easier and thus cheaper to fix than a problem found during testing, or worse, found by an end-user.
  3. Code inspections should also verify that problems found in earlier inspections are solved by the responsible developer.
  4. When you know the number of serious problems in the code before and after an inspection, you can keep track of the quality of the code produced by the team.
  5. The least experienced developers in the team can learn a lot from code inspections. And that doesn't necessarily mean inspections on their code. Especially code inspections on code created by the (self-proclaimed) guru's in the team can be very educating. And be fair, your most experienced developers are usually the ones responsible for the more important parts of your project.

One important rule: Code inspections should never be used to evaluate the performance of a developer, only to ensure his/her work improves. You need the support from your development team to make code inspections really work. Using code inspections as a tool to evaluate their performance does just the opposite. But when you use it as a tool to improve the quality of the product being developed, there will only be a few developers that will protest against inspections.

If you want to learn more about code inspections, check out some of these lines:

  • Michael E. Fagan worked at IBM and formalized and introduced code inspections back in 1976. His website, as well as electronic versions of his books can be found at www.mfagan.com. Check out the resources section. IBM still promotes code reviews, for example in Java development.
  • GoldPractices.Com has a section on code inspections. You can find a full description of the code inspection process here.
  • Another interesting read is “Software inspections are not for quality, but for engineering economics“, by Tom Gilb. Tom Gilb teaches code inspection methods and is considered an authority on code inspections. Some of the companies he works for: Nokia, Intel, Microsoft, Sun Microsystems. The document argues that “Inspection should be used as a specification Quality control tool. The 'quality being checked' is the specification consistency with your best practice standards.

Use all the tools you can

Tools can make the life of a software developer so much easier. A lot of stuff developers do is repetitive work. We keep writing the same type of objects over and over again. Creating the same type of CRUD stored procedures again and again and again. The same applies to checking code. You can of course read every single line of code and think about the consequences, but there are tools that can do that too.

I have a short list of tools that I use. You can find it here. The majority of these tools are freeware. I use them to perform tasks I need to do on a regular basis. An even larger list of tools can be found here.

Tools exist for various development tasks:

  • Profilers. Profilers are a great help when looking for performance issues. Memory profilers exist to check the memory usage of your application. This can help you find problems related to memory usage. Other profilers can measure the performance of your application and/or database. Only recently, I was able to reduce the time used to create a report for one of our clients from 4 hours to 4 minutes, 60 times faster! This was possible by profiling the actions performed on the database. They can also help you in deciding if you really need to build a certain component yourself, or if the library version is fast enough. One I've used on several occasions is Devpartner Studio, by Compuware. Not freeware, but a very professional tool. It contains profilers for memory usage, overall application performance.
  • Code inspections. A lot of things that could be wrong in your code can be found using tools. FxCop for example is a freeware tool that can check your .Net assemblies for various mistakes. Devpartner Studio, by Compuware, which I mentioned before also contains tools that will check your .Net code for common mistakes. It also produces code complexity calculations to give you an indication about the complexity of your code. For this you can also use the community edition of DevMetrics. This freeware version will produce code complexity calculations which can help you find the complex parts of your application.
  • Visual Studio Add-ins. These are simply great. An add-in extends the standard functionality of Visual Studio to make life as a developer a lot easier.
  • Code generators. This can really make developing software fun. As I said earlier, a lot of repetitive work can be eliminated when you use code generators. That allows you as a developer to focus more on the functionality of the application, and less on tedious tasks such as CRUD operations on a database.
  • Version Control management. Whatever someone might suggest, you cannot live without a proper Version Control Management tool. Use Visual Source Safe, Rational Clear Case, or the open source Concurrent Versions System. And there others. Just make sure you use one. These tools can save your life when you screw up. Professional developers store their working code into a system such as the ones I mentioned. When they screw up, they can retrieve the most recent working version. It also allows all team members to gain access to code you're working on. So that when you leave the team (holidays, sick leave, permanently), some one else can take over. It also allows you to see what was changed over time and by whom. Anyone who says you don't need such a tool is either a very bad developer, or should have his brain examined.

Test your work

"If it compiles, it works, because I'm the greatest developer on the face of this Earth". I sometimes make that statement, and so do some others, but never seriously. Yet I've actually met people that really meant this. Obviously, the code will do something after compilation. But will it do what was intended in the first place? So make sure the code you've created is as fantastic as you say it is: Test it!

Every component I develop (web service, class library, etc) is tested using NUnit, a freely available tool to create Unit test. A unit test, for those still in the dark, is a set of procedures that will call the methods in your class library (or web service) and check the result for each of these calls. When you know what the methods will do, you will also know what the results of these methods will be. In a unit test, you will check for these results. Once you've created the tests, and have established that the results are correct, you have a repeatable test for your class library. When you make changes to the components, you can run the unit tests as way of regression test. When the results are still OK, your component is probably still OK. One important thing to remember when you write these tests: Make sure the unit test is accurate and will test the full functionality of the method(s) or component(s). 

Applications should also be tested. Ideally there would be a test plan. But if that is not the case (and let's be honest, that does happen more than once...), then the functional design could give you some guidance when you start testing.

Be careful with new technology 

Another thing all developers want (and I'm no exception to the rule) is that we want to use the newest and coolest tools at our disposal. And sometimes we have to. But using beta versions of Visual Studio, SQL server for development purposes can be very dangerous.

First problem of course is stability. And not just the product stability. You stand the risk of having to rebuild a lot of your code when the next Beta release becomes available. Microsoft specifically mentions if applications developed using a Beta release is allowed to go live. It has happened that applications created using a Beta 1 release did not work when Beta 2 was installed. And believe me, only a few customers are actually interested if you've developed an application using the latest tools. Most are only interested in having a product developed that actually works!

Choose your standards wisely

I'm treading on thin ice here. I'm not an architect, and I have no intention to pretend I'd like to be one. I just need to get this of my chest.

As a developer, I'm always confronted with whatever is the latest craze my software architect thinks is the ultimate in software development. The best example at this time of course is SOA. Now don't get me wrong. SOA is a useful architecture, especially when dealing with web services. But why does suddenly everything need to be a service? I can understand that when I need to access a centrally controlled customer database, that this will ideally be done using a web service owned by the database owner. And the same is true for other centrally owned data.

But what if I build an application to handle orders and contracts for a certain company? Do I need to create a service for orders, and one for contracts? Or maybe even add another service for products that only exist in that company? Some architects will say yes, because since the advent of SOA, everything needs to be a service. Because we use a service oriented architecture and then everything is loosely coupled and prepared for the future. We may need each of these entities in another not yet conceived product for some functionality a future customer might think of.

I would argue no, because the orders and contracts are owned by my application. And the products only exist in this company. Yes, I might need to open-up the system being built to other systems. That would be done using one or more web services, of course. But there has to be a very good reason to develop orders, contracts and products as services. I'm not saying it will not work, because I know from experience that it will, but it causes all sorts of additional problems that need to be solved.

Take for example something simple such as building a report. For the sake of this argument, assume we have 3 services: customers, orders and products. In the pre-SOA world, all this information would probably exist in one database and reports combining these entities can be based on a simple query. But now that we have services for each of these, we need to somehow combine that information ourselves. Be it in code and then presenting the new data to the report, or by means of a data warehouse. And then we have data in several places and different states.

Again, SOA has a lot of valid uses. I also feel that there are numerous situations where it is the architecture of choice. But architects should think about what to choose, rather then going for the new and cool stuff. Use SOA when you have to, not because you want to. And that of course applies to every development standard (UML, RUP, Agile, SOAP ...). Because I don't think there is one ultimate development standard, but rather one for each situation.

Concluding

I just wanted to vent these thoughts. They've been on my mind for months now, and I finally found the inspiration to put it all on my blog. If this has offended you in some way, I'm sorry. If you don't agree to something I mentioned here, again I'm sorry.

If it has made you think, good, that's an additional bonus for me I would like to know what other feel about the subjects I've been rambling on about. If something is completely wrong, let me know, feel free to comment, I'm still learning.

Comments

Erwyn van der Meer said:

Jan, congratulations on a very good article. Should be next week's featured article on the homepage of BloggingAbout.NET! I largely agree with the points you make. Some are so obvious to me that it puzzles me every working day why lots of developers don't abide by these coding standards.

New technology should be used if the productivity gains outweigh the problems of beta software. If the gains are not worth the risks, use proven technology. Of course you have to try out the beta software on a small scale to get a feeling for the gains and risks.
# July 28, 2005 2:23 PM

Edward Bakker said:

Jan, nice piece of work! I don’t think you have to apologize for people who feel offended by your article because in my opinion these are all valid issues!
I haven’t seen a lot of projects with people working on it that have almost 18 years of IT experience. Try to convince the architect on your project to choose the appropriate architecture for the job. At Tech Ed I heard somebody talk about a totally new architecture called BCA (Buzzword Compliant Architecture) ;) works all the time!
# July 29, 2005 2:46 AM

Patrick Wellink said:

Excellent article !!!

I only have a little addition....

If you test something, try to test it with as much as possible....

Let a method run for a night ( while you are sleeping) and inspect memory usage and stuff like that.

If you are using a database, spend 5 minutes to create an application that will fill the database for you. And test, not with 5 records in a database but with 50.000 at least.....

Then you know performance won't degrade after the first two months the customer uses it.



# July 29, 2005 5:24 AM

Dennis van der Stelt said:

[quote]Should be next week's featured article on the homepage of BloggingAbout.NET![/quote]
Done!

Haven't read the article yet though! ;) But I have a feeling it's at least worth the reference.
# July 30, 2005 4:20 AM

Wim van den Brink said:

Hear hear ;-)

I have a little less experience but the same idea's and feelings ..
I like the idea of BCA ;-)
# August 7, 2005 11:20 PM

Nathan J Pledger said:

Absolutely right! (It must be, 'cos I put the same standards in my current place of work)

However, in real life, I see that the extensive libraries I carry around with me, which are XML documented, which are commented and are packaged in meaningful namespaces are not used by my colleagues.

I wonder why this is. I have published the XML documentation, I advise of changes to the various API's or libraries using a techie mailing list and I package them in every project I work with - so everyone will experience them (even if a useful function 'accidentally' pops up in IntelliSense) at some point, so why not use them?
# August 16, 2005 10:30 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Please add 4 and 8 and type the answer here: