The Inquisitive Coder - Davy Brion’s Blog

Trying to walk that thin line between intelligence and ignorance

Archive for June, 2007

Multilingual data and NHibernate

Posted by Davy Brion on 28th June 2007

Some applications need multilingual application data. Not just the user interface, but the actual data. There are different ways of handling this. Some people provide extra columns in their tables for translated values. Obviously, that’s a bad solution. Other people create an extra translations table for each entity that has translatable columns. Better, but all those extra translation tables really clutter the data model. I prefer to store all translations in one table. This can be cumbersome to implement, but the following approach with NHibernate actually makes it pretty easy to work with.

First, create the following tables and sequences (I’m using Oracle btw…):

CREATE TABLE languages
(
  languageid NUMBER NOT NULL PRIMARY KEY,
  "name" VARCHAR2(50) NOT NULL,
  isoname VARCHAR2(2) NOT NULL UNIQUE,
  isdefault NUMBER(1,0) NOT NULL,
  version NUMBER NOT NULL
);

CREATE TABLE translations
(
  translationid NUMBER NOT NULL PRIMARY KEY
);

CREATE TABLE translationvalues
(
  translationvalueid NUMBER NOT NULL,
  translationid NUMBER NOT NULL,
  languageid NUMBER NOT NULL,
  "value" VARCHAR2(4000) NULL,
  version NUMBER NOT NULL
);

ALTER TABLE translationvalues
  ADD CONSTRAINT translationvalues_uc_1
  UNIQUE (translationid, languageid);

ALTER TABLE translationvalues
  ADD CONSTRAINT translationvalues_fk_1
  FOREIGN KEY (languageid) REFERENCES languages (languageid);

ALTER TABLE translationvalues
  ADD CONSTRAINT translationvalues_fk_2
  FOREIGN KEY (translationid) REFERENCES translations (translationid);

CREATE SEQUENCE sq_languages;
CREATE SEQUENCE sq_translations;
CREATE SEQUENCE sq_translationvalues;

The classes look like this:

translations class diagram

and these are the mappings:

  <class name="Language" table="languages">
    <id name="Id" column="LanguageId" type="Int32">
      <generator class="sequence">
        <param name="sequence">sq_languages</param>
      </generator>
    </id>

    <version column="version" name="Version"
	unsaved-value="negative" generated="never"/>

    <property name="Name" column="Name" type="String"/>
    <property name="IsoName" column="IsoName" type="String"/>
    <property name="IsDefault" column="IsDefault" type="Boolean"/>
  </class>

  <class name="Translation" table="translations">
    <id name="Id" column="translationid" type="Int32">
      <generator class="sequence">
        <param name="sequence">sq_translations</param>
      </generator>
    </id>

    <set name="TranslationValues" inverse="true" lazy="false"
	fetch="join" cascade="all-delete-orphan">
      <key column="TranslationId"/>
      <one-to-many class="TranslationValue"/>
    </set>
  </class>

  <class name="TranslationValue" table="translationvalues">
    <id name="Id" column="TranslationValueId" type="Int32">
      <generator class="sequence">
        <param name="sequence">sq_translationvalues</param>
      </generator>
    </id>

    <version column="version" name="Version"
	unsaved-value="negative" generated="never"/>

    <many-to-one name="Translation" class="Translation"
	column="TranslationId" not-null="true"/>

    <many-to-one name="Language" class="Language"
	column="LanguageId" not-null="true"/>

    <property name="Value" column="Value" type="String"/>
  </class>

Alright, now it’s time to actually use this stuff… Suppose you have a Product entity and the Name of the Product has to be a translatable field. The Name property of the Product class would be mapped like this:

    <many-to-one name="Name" class="Translation" column="NameTranslationId"/>

Creating a product with its translations is now as simple as this:

   IList languages = session.CreateCriteria(typeof(Language)).List();

   Product product = new Product();
   product.Name = new Translation();

   foreach (Language language in languages)
   {
      product.Name.AddTranslationValue(language, "Name in " + language.Name);
   }

   session.Save(product);
   session.Save(product.Name);
   session.Flush();

The Translation class has an indexer property which provides easy access to specific translation values so you could easily modify the translations like this:

  product.Name["en"] = "English Name";
  product.Name["nl"] = "Dutch Name";

This approach makes it really easy to work with multilingual data and NHibernate takes care of all the messy details for us :)

Share/Save/Bookmark

Posted in NHibernate, Software Development | 16 Comments »

The Arrival

Posted by Davy Brion on 27th June 2007

Well, the MacBook arrived today. A coworker of mine got his about a week ago and he advised me not to boot up the laptop until i’d given the battery a full charge cycle. It would only take about 4 hours. I don’t know about you, but when i get a new toy like this i can’t wait 4 hours to play with it. Nevertheless, i followed the advice and i charged the battery first. Luckily, only 90 minutes later it was fully charged and i was ready to play.

Everything worked out of the box and after downloading the latest updates (all 5 of them) i downloaded Parallels Desktop. This product is truelly amazing. It’s like VMWare or Virtual PC except without the suckage. So i get ready to install my virtual copy of Windows XP Pro (or as i consider it, my shell for running Visual Studio) and Parallels offers me an automated XP install option. I simply selected the .iso file and let Parallels work its magic. 17(!!) minutes later i had an XP desktop running within my OS X session.

Now as most of you know, i can’t stand Windows. There’s something about it that quite frankly annoys the hell out of me. Once again, it’s Parallels to the rescue. Enter “Coherence” mode. This allows you to hide the XP desktop and it nicely integrates your windows apps into your OS X session. I’m too lazy to create screenshots but if you visit the link earlier in the post you’ll see what i’m talking about. Allright, what’s next? Well it is Windows after all so we better get all the updates. Luckily, my install CD already had SP2 slipstreamed. So about 95 updates later (and no, that wasn’t a joke…) i had a fully patched XP system. I then installed Visual Studio 2005 Professional and the MSDN documentation. So far, i’m extremely impressed with the performance of windows apps within Parallels. Overall, i’d say Parallels is definitely worth the $80. And there’s nothing like setting up an XP system to make you appreciate OS X again. I really do have a newfound respect for Windows users now. The crap they willingly go through… simply astonishing!

Ok so that covers the Windows side of things. What about OS X? It ran very smooth on my 1.6Ghz G5 iMac, and it obviously runs even better on this 2.16Ghz Core 2 Duo. I know most of you aren’t OS X users so i won’t go into further detail about how cool it is. Sooner or later, you’re going to experience this yourself anyway ;)
So what about the hardware? Well, the macbook itself looks gorgeous. The attention to detail is incredible and just looking at it makes you wonder why Dell can’t even manage to create a laptop that looks halfway decent, let alone one that isn’t downright laughable. When running, the machine is hardly audible. In fact, you really have to stress the CPU or put a CD/DVD in the drive to hear anything at all. The keyboard is a joy to use, and in my humble opinion it feels better than the macbook pro’s keyboard. The screen is fantastic… at first i was a little worried that the glossy screen would be annoying, but so far it hasn’t bothered me yet. I’m actually very impressed with it.

So all in all, i’m very happy with my purchase and i’d definitely recommend this laptop to anyone :)

Share/Save/Bookmark

Posted in Off Topic | 6 Comments »

A Brand New Classic

Posted by Davy Brion on 24th June 2007

I’m currently reading Gerard Meszaros’ xUnit Test Patterns book. This book was released in the last month, but i think it’s safe to call this book a Classic already. I think it’ll be soon considered to be as influential as Martin Fowler’s Refactoring book. Perhaps even more influential in a few years.

Either way, this is a must-read. It follows the same style as Refactoring, starting off with the narrative chapters followed by a list of ‘test smells’ and then the catalog of test patterns. If you’re into test driven development or are just forced to write tests at your job, you should definitely read this book. If you’re into TDD you’ll appreciate learning a lot of new ways to improve the quality of your tests. If you’re not into it but are forced to at work, you’ll appreciate the material in this book for making your job suck less. Hell, this book might even convince you that TDD is indeed A Good Thing(tm).

Share/Save/Bookmark

Posted in Books, Test Driven Development | No Comments »

Why you should write tests before code

Posted by Davy Brion on 24th June 2007

It’s often hard to convince developers to write tests before writing the actual code. At least one of my readers (Hi Stefan! ;)) knows all too well how hard it was to convince me. I didn’t really believe it would be that beneficial to our projects. I could not have been more wrong. These days, i’m very much convinced that writing tests before writing code offers many advantages. Not only does it improve the code, it increases the chance of a successful project and can make developers better than they already are. Nevertheless, there are still lots of highly skilled developers that don’t do it.

So this is my list of reasons (in no specific order) why you should be writing your tests first:

  • It leads to developer-friendly API’s. When you write the test, you’re already the first user of your class. You’ll automatically define an intuitive API simply because you’re forced to think about it before you do anything else. This is one of the most underrated benefits IMHO.
  • If you do it right, there will be no unnecessary code. We’ve all been there… you’re implementing a feature and suddenly you think of something else you also need to write. A lot of times, that something else you write turns out to be unnecessary. And code that shouldn’t be there is a shame. The best quote i ever read about code was something like “code is not finished when there’s nothing left to add, it’s finished when there’s nothing left to remove”. I don’t remember who originated it, but it’s oh so true. This unnecessary code is just a waste of time. That code wasted time while it was being written, and it will continue to waste time everytime it is read. Think about that. How often have you spent time trying to figure out code and you weren’t really sure if it was actually being used? If you write your tests, and then only write the code to make the tests pass you should be able to avoid unnecessary code. It’s not always easy and it’s a matter of discipline but it’s really a goal you should be striving for.
  • It leads to better code. Code that is easily testable is usually flexible code. Flexible code is easier to change and improve. And the tests back you up while improving the code to make sure you didn’t introduce errors.
  • It increases the skills of your developers. In more than one way actually. When developers write code, they make mistakes. Every last one of them. The sooner you learn about the mistake, the higher the odds that you’ll avoid the mistake next time around. Some bugs aren’t discovered until the system is already in production. Often, the developer that made the mistake is not around anymore. How is he gonna learn from the mistake then? He won’t. If he has a test that will inform him of his mistake immediately after writing the code, he will have learned something. Just to be clear: i’m not saying that writing tests first will eliminate all bugs. It won’t. But it should severely reduce them. Another area where the developers will improve is design. The more tests they write, the more they will learn about creating code that is easy to test. And if it’s easy to test, it’s easy to change thus indicating good design.
  • A code base that is the result of test-first development is a code base that can be modified in a safe way. It allows developers to confidently make changes to code. We’ve all been in the situation where you need to fix a bug, but you’re affraid of changing the code because it’s very likely that you’ll introduce new bugs. If you have an extensive suite of tests, you should immediately know if you’ve introduced new bugs. This allows you to confidently make the change you think is the best one. Make the change, run the tests and if everything remains green, perfect! If it turns red, great! You’ll know it was the wrong fix before your customers, your manager and your boss knows about it.
  • Writing tests first allow you to significantly reduce defects. You’ll never write bug-free software. It’s very important that you realize that. But you should at least try to minimize the amount of defects in the software you develop. If you write your tests first, you’ll not only get instant feedback on newly written code, but you’ll also be better protected against regressions in the existing code.

This list is far from complete… these are just the benefits that i can think of at the top of my head.

I’m probably preaching to the converted already, but at least now I can simply direct the uncoverted to this post instead of repeating the same thing over and over again :)

Share/Save/Bookmark

Posted in Rants, Software Development, Test Driven Development | 1 Comment »

New theme

Posted by Davy Brion on 23rd June 2007

It’s only been a week and i’m already changing themes… The previous theme (ChaoticSoul) looked great, but it wasn’t very good for displaying code. This theme (Simpla) is not as good looking, but does increase the readability. It’s a nice theme though… nice and simple :)

Share/Save/Bookmark

Posted in About The Blog | 2 Comments »

Integration Tests with NHibernate

Posted by Davy Brion on 22nd June 2007

In my last post i experimented with a way to run my integration tests without polluting my database. I created a specific TransactionFactory which NHibernate would use to create transactions whenever they were requested. My factory returned a transaction which would actually rollback the transaction, instead of committing it. This way, the transactions were not committed during test runs, and the code being tested did not have to be changed. It works, but it gets messy very quickly if an integration test would call multiple methods that were transactional. The test transaction would have to stay alive during the entire test, and would have to be reused by all the transactional methods called in that test, all without changing the code being tested. It’s doable, but i didn’t feel too good about it.

I looked for other options and i believe i’ve found a pretty good one. It would be great if i could somehow wrap every data access call caused by a test into one MS DTC transaction. Then, after the test i’d simply have to abort the MS DTC transaction. The database stays clean, the tests remain independent of what may already be in the database and most importantly, i wouldn’t have to change my production code.

So, what do i need here? First i need a way to connect an NHibernate session to the current DTC transaction. And i also need a custom TransactionFactory for NHibernate to use which will return dummy transaction objects which do nothing. The production code will receive these transaction dummies whenever a transaction is requested and will call Commit() on them when needed. Obviously, the Commit() implementation of my dummy transaction is a no-op.

Let’s start with connecting an NHibernate session to a DTC transaction. NHibernate provides access to the underlying database connection through the ISession.Connection property which returns an IDbConnection. Most objects that implement IDbConnection have an EnlistDistributedTransaction() method, which does exactly what we want, but it’s not defined in the IDbConnection interface. The only one that doesn’t have this method as far as i know, is the implementation in the System.Data.SqlServerCe namespace. I don’t use SqlServerCe so that’s not a problem for me.

I want my production code to request NHibernate sessions through my own provider which implements the following interface:

public interface ISessionProvider
{
  public ISession GetNewSession();
}

At runtime, the real SessionProvider will be used which will provide NHibernate sessions which use the default AdoNetTransactionFactory and AdoTransactions. At unit-test time, the following ISessionProvider will be used:

public class SessionUsingDtcProvider : ISessionProvider
{
  private ISessionFactory _sessionFactory = null;

  private ISessionFactory SessionFactory
  {
    get
    {
      if (_sessionFactory == null)
      {
        NHibernate.Cfg.Configuration configuration =
           new NHibernate.Cfg.Configuration()
              .AddAssembly("MyMappingAssembly");

        ISessionFactory sessionFactory =
           configuration.BuildSessionFactory();

        // overwrite the NHibernate TransactionFactory so it will use our
        // own factory. check the previous post if you don't know why
        // i do it this way ;)         PropertyInfo propertyInfo = sessionFactory.Settings.GetType()
            .GetProperty("TransactionFactory");
        propertyInfo.SetValue(sessionFactory.Settings,
             new TestTransactionFactory(), null);
      }

      return _sessionFactory;
    }
  }

  public ISession GetNewSession()
  {
    ISession session = SessionFactory.OpenSession();
    EnlistInDtcTransaction(session.Connection);
    return session;
  }

  private void EnlistInDtcTransaction(IDbConnection connection)
  {
    MethodInfo methodInfo = connection.GetType()
       .GetMethod("EnlistDistributedTransaction",
          BindingFlags.Public | BindingFlags.Instance);

    methodInfo.Invoke(connection, new object[]
      { (System.EnterpriseServices.ITransaction)
           ContextUtil.Transaction
      });
  }
}

So the EnlistDistributedTransaction() method is called through reflection because it’s not defined in the interface. I wouldn’t do this for production code, but for test-code i think it’s OK.

The TestTransactionFactory class looks like this:

public class TestTransactionFactory : ITransactionFactory
{
  public void Configure(System.Collections.IDictionary props)
  {
  }

  public ITransaction CreateTransaction(ISessionImplementor session)
  {
    return new TestTransaction();
  }
}

And the TestTransaction is as dumb as it possibly could be:

public class TestTransaction : ITransaction
{
  public void Begin(System.Data.IsolationLevel isolationLevel)
  {
  }

  public void Begin()
  {
  }

  public void Commit()
  {
  }

  public void Enlist(System.Data.IDbCommand command)
  {
  }

  public bool IsActive
  {
    get { return true; }
  }

  public void Rollback()
  {
  }

  public bool WasCommitted
  {
    get { return false; }
  }

  public bool WasRolledBack
  {
    get { return false; }
  }

  public void Dispose()
  {
  }
}

Now suppose you have the following code in your business layer:

public class CustomerService
{
  private ISessionProvider _sessionProvider;

  public CustomerService(ISessionProvider sessionProvider)
  {
    _sessionProvider = sessionProvider;
  }

  public void SaveCustomer(Customer customer)
  {
    using (ISession session = _sessionProvider.GetNewSession())
    using (ITransaction transaction = session.BeginTransaction())
    {
      session.SaveOrUpdate(customer);
      session.Flush();
      transaction.Commit();
    }
  }
}

As you can see, this code requests a transaction and commits the transaction after the data is inserted or updated in the database. At runtime, this is exactly what i want. But during my tests, i don’t want this to actually be commited.

So now i could test this without polluting my database like this:

[TestClass]
public class MyTestClass
{
  [TestInitialize]
  public void TestInitialize()
  {
    SetUpDtcTransaction();
  }

  private void SetUpDtcTransaction()
  {
    ServiceConfig serviceConfig = new ServiceConfig();
    serviceConfig.Transaction = TransactionOption.RequiresNew;
    ServiceDomain.Enter(serviceConfig);
    ContextUtil.MyTransactionVote = TransactionVote.Commit;
  }

  [TestCleanup]
  public void TestCleanup()
  {
    AbortDtcTransaction();
  }

  private void AbortDtcTransaction()
  {
    ContextUtil.MyTransactionVote = TransactionVote.Abort;
    ServiceDomain.Leave();
  }

  [TestMethod]
  public void TestSaveCustomer()
  {
    CustomerService service =
       new CustomerService(new SessionUsingDtcProvider());

    Customer customer = new Customer();
    customer.Name = "Davy Brion";

    service.SaveCustomer(customer);

    Assert.IsTrue(customer.Id > 0);
  }
}

Mission accomplished :)
Note: this test instantiates the SessionUsingDtcProvider which will create the NHibernate SessionFactory which is a rather expensive operation… In your production code, the correct SessionProvider should only be created once and made available so the rest of the code has easy access to it.

Update: it’s no longer necessary to set NHibernate’s TransactionFactory through reflection. Read this…

Share/Save/Bookmark

Posted in NHibernate, Software Development, Test Driven Development | 4 Comments »

NHibernate ignores hibernate.transaction_factory setting

Posted by Davy Brion on 21st June 2007

I want to be able to run my integration tests in their normal setup, but at the same time I don’t want the database actions caused by my tests to be committed to the database. And since my business layer manages the transactions (and thus, calls Commit() on them) i needed a way to make sure that those Commit() calls wouldn’t actually commit to the database when the code was executed by the integration tests.

Luckily, NHibernate offers a configuration option (hibernate.transaction_factory) where you can specify which ITransactionFactory type should be used at runtime. Excellent! I could just tell NHibernate to use my specific TestTransactionFactory which would keep returning the same TestTransaction during the execution of a single test. The TestTransaction would silently ignore calls to Commit() and rollback automatically when it is closed or goes out of scope.

Granted, there are probably much cleaner ways to achieve this, but at the moment i can’t think of a better way. So if you know a cleaner way, by all means consider this post an extensive brainfart and please post the preferred solution :)
Until then, let’s continue…

So, I created my TestTransactionFactory which implements the ITransactionFactory interface and i let it return a cached instance of TestTransaction whenever a transaction is requested. A TestTransaction instance simply wraps an NHibernate.Transaction.AdoTransaction object but ignores calls to Commit() and automatically rolls back the transaction when it is closed or goes out of scope. Then, i set the hibernate.transaction_factory setting in my config file to my own factory.

And this is the test:

[TestMethod]
public void TestFakeTransactionRollsBackInsteadOfCommit()
{
  using (ISession session = SessionProvider.GetNewSession())
  {
    ITransaction transaction = session.BeginTransaction();

    transaction.Commit();
    transaction.Dispose();

    Assert.IsTrue(transaction.WasRolledBack);
  }
}

So i ran the test once i told NHibernate to use my own factory… but it failed. NHibernate was still using an AdoNetTransactionFactory. After making sure i didn’t screw up, i looked in the NHibernate source code (yay for open source!) to find where the transactionfactory was created and found this:

ITransactionFactory transactionFactory = new AdoNetTransactionFactory();

Simply inexcusable… They provide the interface and the configuration option, and then they completely ignore it. After swearing loudly for a few moments, i decided to just overwrite the transactionfactory using reflection.

So now, my test looks like this:

[TestMethod]
public void TestFakeTransactionRollsBackInsteadOfCommit()
{
  using (ISession session = SessionProvider.GetNewSession())
  {
    ITransactionFactory originalTransactionFactory =
      session.SessionFactory.Settings.TransactionFactory;

    PropertyInfo propertyInfo = session.SessionFactory.Settings.GetType()
      .GetProperty("TransactionFactory");
    propertyInfo.SetValue(session.SessionFactory.Settings,
      new TestTransactionFactory(), null);

    ITransaction transaction = session.BeginTransaction();

    transaction.Commit();
    transaction.Dispose();

    Assert.IsTrue(transaction.WasRolledBack);

    propertyInfo.SetValue(session.SessionFactory.Settings,
      originalTransactionFactory, null);
  }
}

And it works. I would like to point out that i’d never do this in production code, but for the sake of keeping my database clean while running my integration tests i think this is acceptable.

Update: this issue has been fixed

Share/Save/Bookmark

Posted in NHibernate, Software Development | 4 Comments »

Introduction to the upcoming ADO.NET Entity Framework

Posted by Davy Brion on 17th June 2007

John Papa posted a nice introduction to Entity Framework. If you’re new to Entity Framework (like me) then it’s definitely a good read.

One thing i already dislike about EF is that it uses 3 kind of mapping files:

  • Conceptual Schema Definition Language (CSDL) to define your domain entities
  • Store Schema Definition Language (SSDL) to define your database tables
  • Mapping Schema Language which contains the actual mappings between the domain entities and the database structure

This really seems excessive. With NHibernate, all of this information is stored in one mapping layer. You might argue that it is conceptually cleaner to split up all of this information, but for now it seems rather impractical to me.

I hope they change this before the final version is released.

Other than the mappings, it looks pretty nice. And they already announced that the final version will support Persistance Independence so it should get even better :)

Share/Save/Bookmark

Posted in Entity Framework | No Comments »

Back from (N)hibernation

Posted by Davy Brion on 17th June 2007

I haven’t posted anything in a while, but recently i’ve been playing around with NHibernate which sparked my interest in playing around with .NET again. A little over a year ago i sold my windows laptop which only left me with my iMac G5. The G5 chip is a PowerPC chip which ment i couldn’t run Windows on it. No biggie, i thought. I disliked Windows anyway, and i was already using .NET at work all day so i figured i’d be fine. So at home, i switched to Java to scratch my coding itch.

Now, i think Java is a very nice language and i enjoyed writing a new IrcLeech version in it. But once i got IrcLeech working in Java, i never really found something else i wanted to do in it. So then i started playing around with Objective C and Cocoa to do some native OS X programming. And while those technologies are very cool, i didn’t really find something cool i wanted to work on.

So about 2 weeks ago, i was finally able to play with NHibernate in a little experiment at work. I like the technology so much i really want to get involved with the project, and some other projects as well. So… i ordered a new Macbook so i’ll still have OS X, but now i’ll be able to run Visual Studio in a parallels desktop session alongside my OS X session. So once the laptop arrives, i plan on getting very familiar with the inner workings of nhibernate and perhaps even contribute to the project. There are some other projects i really wanna play with as well, such as Castle’s DynamicProxy, Castle’s ActiveRecord, Ayende’s Rhino Mocks and several more. Should be a lot of interesting stuff :)

Share/Save/Bookmark

Posted in About The Blog | No Comments »

Programming Languages Don’t Matter

Posted by Davy Brion on 17th June 2007

Note: this was originally written on August 28, 2006

Programming languages have been the topic of endless discussions for years now, and a lot of people take these things very seriously. Well, a lot of developers take these things very seriously. Normal people don’t care, and boy are they right. Some developers will stick with a certain language purely for syntactical reasons. And some will dislike a language because of its syntax even though the language itself might be extremely powerful. Other developers prefer languages which mainly provide improved productivity, even though the syntax might not be as elegant or even cool. And let’s not forget the developers who choose a language based solely on how many jobs are available for that language.

I’ve only been working as a software developer for 4 years, but i’ve been writing code for the last 10 years. During those years i’ve written code in C, C++, Visual Basic, C# and Java. I’ve played around with other languages as well, but not enough to actually count them among the languages i’ve done anything more than trivial stuff in. One of the most important things i’ve learned is that the language simply doesn’t matter. A language can make some things easy, and some things hard. But in the end, the language is just a tool to help you write your code. The way you design and write your code should be done independently of the language you use.

I’ve always said that coding is like talking. Once you’ve learned to talk, you can learn any language to express your thoughts and feelings. It’s the same thing with coding. At least, it should be. Once you’ve learned to code, you should be able to write code in any language they throw at you. It’s just a matter of learning the syntax. The tricky part is that some languages will try to push you into certain directions that may or may not be the right path for you to take. Visual Basic is a prime example of this. Visual Basic tries to persuade you to take certain shortcuts. Shortcuts that lead to sloppy, ugly and even unmaintainable code. But it will be easy to write. At least, that’s what they (and i’m pointing at Microsoft here) want you to think. In reality this easy code will be your worst nightmare once you have to maintain the code over a long period of time. But does that mean that Visual Basic is an inferiour language? A language so bad it’s impossible to write good code in? No. A good developer will write good code in Visual Basic. Because a good developer knows how to write code ‘into’ a language, instead of ‘in’ a language.

Programming into your language, instead of in it is a concept that is explained in the classic software development book Code Complete by Steve McConnell. It basically means that as a developer, you should think of what you need to do, and how you want to do it, and then assess how to do that in the language you are using. If that’s how you approach writing code, you are programming into your language. But most developers let their language and environment dictate the way they write their code. These developers are programming in their language. And they’re gonna have a hard time when they’re forced to move to a new language. Do yourself a favor and stay away from these developers. If you’re hiring people, skip these developers. They may even be highly proficient in their current language but if they can’t think about code outside of their language, they will be a burden on your team once you switch languages in your company.

Knowing the ins and outs of your programming language is very helpful, but i’d never judge a developer based on his/her knowledge of obscure language features. There’s a reason why these things are obscure. Instead, focus on concepts, good programming practices and depending on the ambition of the developer, design patterns. These are the things that make a difference between a good developer, and a not so good developer.

Share/Save/Bookmark

Posted in Rants | No Comments »