Category: Architecture & design

Unfortunately, Figure 1 is not correct; we’re working on getting that fixed in the article, but in the meantime here’s a corrected version:

The WPF Utilities component should not depend on any unit tests

The unit test components should not depend on any other unit testing component

The domain model should NOT depend on the data access layer. Instead, the data access layer should depend on the domain model. The domain model is the core of everything.Â Achieving this is not easy, and I’ll post about how to achieve it.

Yesterday, my pair-programming partner mentioned that he thinks code should be art.Â A few weeks ago, another programmer said she wanted to write beautiful code.Â These are awesome goals, and I it made me happy that they even realized these are laudable goals; code, application design, and a running program can (and usually should) be beautiful and elegant.

So, Iâ€™m going to start a series of posts all about beautiful coding, elegant designs, and creating wonderful applications.

The advice on the above stack overflow discussion is very good, and I recommend reading it.Â Â A related post is Joel’ Spolskyâ€™s excellent â€œThe Perils of Java Schoolsâ€.

Certainly thereâ€™s nothing better for learning about how a computer works internally than programming 2D or 3D graphics routines in assembler and linking that to your hybrid C/C++ program managing the rest of your game.Â If youâ€™re using a C++ object oriented approach for the elements of your game (weapons, characters, land tiles, whatever) then you can start to get a sense of good object oriented design.

However, my understanding is that very few game programmers are doing things in assembler these days â€“ DirectX with C/C++ is blazingly fast, and DirectX with .NET is usually fast enough and is much nicer to program in with its automatic memory management and the extensive functionality of the .NET framework.

At the heart of becoming a great programmer is â€“ not surprisingly – a desire to become a great programmer!Â You have to want to write beautiful code using elegant designs to produce wonderful applications.Â You have to want to write code that you can be proud of, even years later.

Itâ€™s going to take at least 10 years.Â Thatâ€™s not 10 years working in a big corporation where 50% of your time is writing TPS Reports, 20% is in meetings, 10% is office gossip, and 10% 😉 is maybe spent fixing somebody elseâ€™s mess with the cacophony of 5 simultaneous conversations about TPS Reports rage in the cubicles around you.

To really learn to program you need to work on things youâ€™re passionate about – a small personal project, or better yet a large personal project.Â Thereâ€™s nothing better than fixing bugs in your own code 2 years later while cursing the idiot that wrote the code for not using a better design and writing some useful documentation.

My own project was a 75,000 line artificial intelligence natural language application written in C++ (and later migrated to C#) that I started shortly after graduating university.Â It was really hard and I made a lot of mistakes.Â I fixed them.Â I made more mistakes, and cursed myself for repeating some mistakes, and then I fixed them.Â Over 3 years I worked on this project a lot; I learned a lot.

Similarly, back in high school and university I programmed games.Â I made a lot of mistakes there too, and I learned a lot.Â A few years ago somebody said to me, â€œI wish I had your knowledge of computersâ€.Â I replied, â€œItâ€™s easy, just devote years of your life to programming something youâ€™re passionate about.â€Â He didnâ€™t seem interested, and fair enough, but thatâ€™s why I can charge a lot for my consulting time.

Of course I still make mistakes, although itâ€™s a lot less now than I used to, and usually I make new mistakes.

I studied math at university, and the amazing thing about studying math is that youâ€™re usually being taught things first discovered hundreds or even thousand of years ago; Newton published Principia Mathematicaover 300 years ago!Â Â Computer science and object oriented programming are really only about 50 years old (and yes, Iâ€™m not talking about the difference engine), so itâ€™s only natural that as a discipline weâ€™re all still learning.Â Which, really, is great because itâ€™s a lot of fun.

I saw some very poor code today, and amazingly it was written by a programmer of 10+ years.Â The programmer had updated an existing class by adding a new parameter â€“ exactly the same parameter – to each and every method of the class.Â In fact, the object couldnâ€™t work properly without this information.Â Hereâ€™s my Java pseudo-code version of the updated code:

It eliminates the need to check the parameterâ€™s validity in every method. Instead, the parameter can be checked once by the constructor.

It allows the variable to be frozen to avoid accidental tampering – in this case using Javaâ€™s â€œfinalâ€, but this can also be done in C#â€™s using â€œreadonlyâ€, or in VB.NET using â€œReadOnlyâ€.

There is no need to deprecate all of the existing methods

It may be possible to leave previous constructors in place and assume a reasonable default, or even use the C++/C#4/VB.NET feature of default parameter values to reduce rework (although this requires a re-compile).

In this case, the change was even more egregious because the class was actually implementing an interface, and the programmer had updated the interface.Â Updating the interface required all implementations of the interface to pass in the â€œxâ€ parameter â€“ but â€œxâ€ was an implementation detail!Â So the other implementations didnâ€™t need anything to do with â€œxâ€ whatsoever!Â (â€œxâ€ wasnâ€™t an integer in the real code).Â Instead, using the constructor approach above, any consumer of the interface remains unchanged, and other implementations that do not rely on â€œxâ€ also remain unchanged, so the impact to the API and the many, many applications that depend on the API is much less.

If I’m right about something it should easily to convince somebody of my point of view.

Now, “easy” might mean doing some research and writing up a small Word document if it’s a professional disagreement at work. It almost certainly means understanding the other person’s context: their point of view, their understanding of the way things work and ought to work, and the constraints they have to work within and why those constraints are there (and if they can possibly be removed, often with creative thinking or bringing somebody else into the discussion and repeating this process).

For example, I had a disagreement with boss about something. Before I tried to convince them I was right, I first asked lots of questions to understand why he thought he was right. I didn’t know the constraints the boss was working under, but I knew that their boss and the boss’s boss were often dogmatic about technology, and I respected the boss as a very intelligent person that always tried to make the best decisions (yes, it was great working with this gentleman!) So I worked hard to understand his constraints.

Once I understood his context, I realized two things: 1. his understanding of the technologies in question was slightly incorrect (he is after-all the boss and slightly removed the technology after 20 years in management) and 2. he was rightly concerned about alignment with strategic technology direction, a few other projects that were doing something similar, larger scale, security initiates and how my suggested technology would worth within those constraints, etc. With that deeper understanding of the problem and solution criteria I did some research, wrote up a small Word document that outlined at a high level how two technologies worked, the pros and cons of both approaches and presented a summary evaluation of both technologies against a more complete set of criteria than I had originally been aware of. In the end we almost always chose the right technology.

This actually happened about 20 times in the 4 years that I had the pleasure of working with this gentleman, and sometimes the technology I had suggested was the better choice, and sometimes once I understood everything better my original thinking was wrong. Thus, this life lesson has an inescapable and important corollary:

If, after correctly understanding the complete problem, understanding all the solution criteria and understanding any other constraints, my original point of view may be wrong. However, that’s okay because we can now choose the right solution together.

And a few times, my original thinking was right, but artificial, capricious and immutable constraints defined by the boss’s boss’s boss (etc) meant that we couldn’t do the right thing, so we chose the best thing we could under the circumstances.

PS. The dogma clause

Obviously sometimes the constraints the other person is working within are their own personal dogma, and therefore absolutely preclude any ability to change their mind regardless of any amount of evidence. Hopefully (and usually?) this is not the case in a professional setting like work. I therefore cast out such situations as obviously not applicable to a professional discussion like this one is pretending to be. I also make it a rule to try my best to avoid issues with people whose personal dogma on the issue overrides evidence. However, it does happen even at work (as it the case with the boss’s boss’s boss etc above). I have found the best solution in such situations is to politely say that you’ll have to agree to disagree, then do what they are asking while looking for another job…