Archive for September, 2008

Looking Back On The Last Project

No Comments »Written on September 16th, 2008 by
Categories: Off Topic

It's always interesting to look back when you're finishing up a project. This was my first project since moving from working at clients to working at our own office. We wanted to make some changes in our way of working so we decided to use some of the wacky ideas i've posted on this blog for this project. More specifically, we used the Request/Response Service Layer and my MVP approach for writing testable ASP.NET Web Forms.

The first 2 weeks were a bit rocky since the other developers had to learn about Dependency Injection, Inversion Of Control and using a mocking framework for most of our tests. In the first 2 weeks, we didn't reach any of our time limits, but then again, we expected that because we knew it would take some time to get used to all of these new things. I actually thought it would take 3 weeks before we would start getting up to speed properly. Luckily, the other developers caught on pretty fast and before we knew it, we started beating the time limits.

Obviously, we did our weekly retrospective after each sprint, and i was particularly interested in how they felt about working according to these new concepts. For the server-side implementation of the Request/Response service layer, i didn't hear a single complaint. Once they got used to it, they seemed very comfortable with the whole Request/Response thing and i think they really liked how the Inversion Of Control container just 'magically' wired everything up. For the client side Dispatcher (used to send Requests and fetch Responses) there was one complaint about having to explicitly clear the state if you had to make 2 trips for some reason. Now, the complaint was actually made because i changed the behavior in one specific case after a few weeks, which broke a few screens, so their complaint was definitely justified.

Another complaint that i heard twice, was that the tests for the Controllers of the Web Forms could get pretty complex or even annoying once you had to deal with complex screens. We never really found a way to make that easier, and i don't really think it can be made easier, to be honest. Complex screens simply require a lot of testing. There's not a lot you can change about that. I definitely prefer writing a bunch of tests over testing it manually all the time. Having said that, it's still important to keep in mind that screens still need to be tested (thoroughly) manually from time to time. No matter how many tests you may have, they simply don't cover everything that happens when a user is actually using it in a browser. By the way, i think i was the biggest offender of this rule.

So how did we do? The project is pretty much finished now... one team member is still working on the project to wrap it all up but he'll probably be finished in a few days. We stayed under budget, and the issues that were reported by the project leader (who's also playing the customer proxy role) were all fairly minor, a lot of them related to stupid UI issues. I think most of the issues were related to my total lack of solid ASP.NET knowledge actually :)

I'm also very proud of the overall quality of the code base. Everything is very readable, simple and flexible while there's nothing bad hidden in there. It's actually the first time in my career where i felt this way about a code base where i didn't write the whole thing myself ;)

Oh and to Joel and Sacha: thanks for doing a great job :)

Code Health

2 commentsWritten on September 14th, 2008 by
Categories: Software Development

When it comes to code, a lot of people are often very opinionated. Supercomputers couldn't even keep track of the number of times i've looked at a piece of code and said "this sucks". We often qualify code as crappy, bad, decent, clean, good, great, whatever else you can think of. The problem is that this usually comes across as a very subjective opinion. What one person might think of as crappy code can be decent or even good to someone else.

I think it would be better if we started talking about quality of code in terms of how healthy the code is. In a very abstract way, software is basically a life form. After its creation, it starts a life of its own. It tries to fulfill its purpose and to do that, it often has to be changed or improved. Depending on how well it was created, it might be capable of easily adapting to whatever is required of it. Sooner or later, the software will reach a point where it can no longer easily adapt, which usually is the beginning of the end of this life form as new software will be prepared to replace it. Ideally, we'd like to keep working software around as long as possible. Not only because of the financial consequences of not doing so, but because we really shouldn't be redeveloping the same systems over and over again.

To keep working software around for a long time, we have to take care of its health. It's important to keep it healthy at all times. As soon as rot is introduced in the internals of a piece of software, it either has to be removed as soon as possible, or it will spread and affect other internals. When too many internals are infected, it becomes very hard or even impossible to help the software. Just like humans need to take care of their bodies, it is important that the code of the software is kept in a healthy state.

So when can we say that code is healthy? When it is easy to modify or improve, without affecting other parts of the system in a negative way. How can we achieve healthy code? By keeping it clean, flexible and readable. To many people, that equals good code. To most managers, the term 'good code' doesn't really mean anything. As long as the code makes money, it's good code for them. But if the code is not healthy, it will stop making money sooner rather than later. Telling them the code is not healthy as opposed to saying it's bad or crappy or whatever signals a possible business problem instead of simply hearing a developer complain about code he doesn't like for whatever reason.

Simply put, communicating about code quality in terms of health allows you to focus on what's really important (the viability of the software) instead of coming across as someone who simply doesn't like the code because of personal preferences.

WCF And Large Amounts Of Data

12 commentsWritten on September 14th, 2008 by
Categories: WCF

If you're using my Request/Response service layer, or any other WCF service that might require sending large amounts of data over the wire, you quickly bump into some limits that WCF enforces by default. Among the billions of configuration options for WCF, there are luckily some options that allow you to easily send large amounts of data from a service to a client.

I typically use the following options:

For my binding configuration i usually set the maxReceivedMessageSize, maxStringContentLength and the maxArrayLength properties to their maximum values:

    <bindings>

      <netTcpBinding>

        <binding name="MyTcpBinding" maxReceivedMessageSize="2147483647" receiveTimeout="00:30" sendTimeout="00:30">

          <readerQuotas maxStringContentLength="8192" maxArrayLength="20971520" />

        </binding>

      </netTcpBinding>

    </bindings>

This example shows these settings for the netTcpBinding... i've also used them with the wsHttpBinding. Not sure how well it works with other bindings though.

I also set the maxItemsInObjectGraph setting of the DataContractSerializer to make sure i don't hit the default limit if i have to send a large object graph over the wire:

    <behaviors>

      <serviceBehaviors>

        <behavior name="MyBehavior">

          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

          <serviceMetadata />

        </behavior>

      </serviceBehaviors>

    </behaviors>

You have to apply these settings both server and client side to get it working properly and you need to refer to these settings in your service and endpoint settings:

      <service name="Brion.Library.ServerSide.WCF.WcfRequestProcessor" behaviorConfiguration="MyBehavior">

        <host>

          <baseAddresses>

            <add baseAddress="net.tcp://localhost/RequestProcessor"/>

          </baseAddresses>

        </host>

 

        <endpoint contract="Brion.Library.Common.WCF.IWcfRequestProcessor" binding="netTcpBinding"

              bindingConfiguration="MyTcpBinding" />

 

      </service>

    <client>

      <endpoint address="net.tcp://localhost/RequestProcessor" binding="netTcpBinding"

            name="IRequestProcessor" bindingConfiguration="MyTcpBinding" behaviorConfiguration="MyBehavior"

            contract="Brion.Library.Common.WCF.IWcfRequestProcessor" />

    </client>

Now, i don't recommend sending such large amounts of data through WCF services... but in the case of using my Request/Response service layer, the amount of data you're sending over the wire pretty much depends on which kind of requests (and how many of them) you're batching so i think it's better to make sure that at least the configuration allows for it. So obviously, it's best to keep an eye on the size of your messages to make sure you're not doing anything crazy. Being able to send your entire database over the wire doesn't mean it's a good idea to actually do so ;)

Technical Interviews: What Questions To Ask?

6 commentsWritten on September 10th, 2008 by
Categories: Interviews

I recently had to do an impromptu technical interview with an applicant at work. I spent the last few years working at clients instead of our home office so it had been a while since i had to conduct a technical interview. So unfortunately, i couldn't really think of great questions to ask. I did ask a few good questions (at least, i think so), but it got me thinking afterward about what would be a great way to conduct a technical interview. I came up with an approach that i think will be pretty good. I haven't tried it yet, but next time i'll definitely do it like this:

  1. Ask if they know the Single Responsibility Principle (SRP)

    Some people will know, some don't. If they don't, explain it to them. If they do, let them explain it.

  2. Ask them to talk about a class in the system they're currently working on that violates the SRP

    In case they didn't know about the SRP, this will quickly tell you how easily they can understand new concepts since you've just explained it. If they did know about it and were able to explain it correctly, they should be able to give you a good example. If they were able to explain it, but can't give you a good example, that's a sign that something isn't right. It might be an indication that the applicant has trouble mixing theory with practice.

  3. Ask them what they would do to fix the problems of that class when given the chance to clean it up

    This should give you some valuable insight as to how the applicant thinks about how code should be structured. I'm not even talking about big design stuff, just simple class design. The answer to this question will most likely enable you to start an interesting discussion about class design and writing code in general, while not distracting the applicant with fictional example classes. After all, we're talking about code the applicant should know pretty well.

And that's it. The discussion that the final question should lead into should tell you most of the things you need to know about the applicant. You can talk about TDD, writing code, refactoring, design, pretty much everything... Depending on the position that's available and the skill-level of the applicant you could also start talking about architecture stuff.

I think this approach allows you to learn a great deal about the applicant's technical skills in about 20 minutes. I personally don't care how well an applicant knows a certain API or library, i'm interested in finding out how well the applicant can deal with new stuff, concepts that he/she may not have any experience with. Basically, how well the applicant can adapt to different technical situations.

Oh, and a quick tip to future applicants: mentioning that you read my blog is a tricky approach. While flattering, i may or may not feel the urge to figure out if you're really reading it or if you're just giving the posts a quick read :P

Introducing TDD: How I Would Do It

6 commentsWritten on September 7th, 2008 by
Categories: testing

I recently asked you how you would introduce TDD to an audience that has little to no knowledge of, or experience with TDD. Oh, with a time limit of 10 minutes. This post is pretty much the outline of everything i hope to say in those 10 minutes.

What Is TDD

  • It is an iterative and incremental way of working, on a coding level.
  • It comes down to a series of little steps that we follow step by step, while never trying to do too much at once.
  • We try to break down our coding activities in small, easy to manage pieces
  • When we need to add/modify behavior in code, we:
    • write a small failing test (sometimes a couple of them, but never too many at once) that indicates the lacking of, or the incorrectness of that behavior
    • write/modify the code to make the test pass, but we do that as simple as possible, perhaps even quick-n-dirty
    • after the test passes, we clean up the code where necessary. While doing so, we focus on keeping the code clean and readable
    • run the tests we just wrote again to make sure everything still works and we didn't break anything
    • run the entire test suite before committing our code to make sure we didn't introduce bugs in other places
  • We try to follow these rules for all of the code we write (not always possible though)

Why do we prefer this way of working?

  • If we stick to the rules, we'll always have clean code that works
  • Our design (in general) is flexible, simple, and never more complex than it has to be
  • It allows us to make changes in the code without fear and with confidence, no matter who wrote the code in the first place. After all, we have an extensive test suite which will alert us immediately when we make a mistake.
  • We can minimize the time we waste debugging and trying to understand why something doesn't work anymore.
  • We won't have any code that isn't being used anywhere.
  • We can increase the skill level and the effectiveness of every developer on the team.

How can you get started with TDD

  • It takes some time before you can do TDD effectively. Don't expect all of the benefits to come immediately.
  • Read Kent Beck's Test Driven Development By Example to get into the TDD mindstate
  • Try it, and stick with it for a while
  • Realize that you will need to learn some new tricks to write code that is easily testable. Read xUnit Test Patterns to improve your skills.
  • After a while, you will not want to go back

What do you think? Anything i left out that i really should mention? Are there things i need to stress more or discuss differently? I still have a few days left to make changes, so let me know :)