The Inquisitive Coder - Davy Brion’s Blog

Trying to walk that thin line between intelligence and ignorance

Archive for the 'Opinions' Category


Junior Vs Senior Developers?

Posted by Davy Brion on 29th December 2008

Chris Brandsma recently wrote an insightful post about how we shouldn’t coddle junior developers. It’s a good post and i can definitely understand Chris’ frustrations on the matter. There’s just one thing i don’t understand though: why do we even differentiate between junior and senior developers?

First of all, what’s the difference between a senior developer and a junior developer? Is it merely the number of years of experience? In previous client engagements, i’ve seen more than my share of bad developers who’ve had years and years of experience. Would i trust those developers more simply because they have the experience required to be called ’seniors’? Hell no. Trust has to be earned, i don’t care if you just graduated or if you’ve been writing code for 5 years or more.

When i have to work with someone i’ve never worked before, i assess this person’s qualities and capabilities on two things: how he thinks about writing code (in general), and how easy he can pick up new concepts/practices/principles. That’s it. A junior developer with little to no experience can often be a lot more valuable than a developer who has 5 years of experience under his belt and just assumes that he knows it all.

With a senior developer, you have to be lucky that he’s learned from his previous mistakes (and every developer makes mistakes, no matter how good he is or how much experience he has), that he hasn’t picked up too many bad habits and that he is open minded. If you can get a senior developer like that, consider yourself very, very lucky because there really aren’t that many of them.

With a junior developer, you can easily mold them into the kind of developer you want them to be. They haven’t really had a lot of time to pick up bad habits, and they are eager to prove that they belong at your company so they will be very eager to learn and improve. All you need is a couple of people who are willing and capable of teaching these young developers.

Of course, with junior developers you do have to live with the fact that they will make rookie mistakes. You have to review their work a bit more, and make sure that they learn from their mistakes. If you do this from the beginning, you’ll quickly notice that the extra reviewing tasks will soon take up less and less work.

At my company, we don’t really differentiate between juniors and seniors. The last couple of years, we’ve pretty much only hired young developers who just graduated. And so far, it’s worked out great. They never get assigned easier tasks or anything like that, and they have to do the same kind of stuff that people with more experience need to do. The result is that we have a bunch of young developers (i think the average age of our developers is 24 or something) who already do a great job, and they’re constantly getting better.

Share/Save/Bookmark

Posted in Opinions | 2 Comments »

Batching Remote Operations Is Not Premature Optimization

Posted by Davy Brion on 12th December 2008

I spent a day at Devoxx (formerly known as Javapolis) this week, and one of the presentations i saw was about common performance anti-patterns, given by Alois Reitbauer from DynaTrace. While i didn’t really hear anything new during the presentation, i did kinda like how the speaker stressed that while premature optimization is indeed evil, certain things simply don’t belong in that category and are things you should definitely keep an eye on throughout the development of your projects.

Those of you who’ve been reading this blog for a while know that i’ve often stressed the importance of reducing the number of remote calls. Yeah that’s right, i just linked to 7 of my own posts in a single sentence :p

Anyways, there were a few people who thought that my preference for batching queries/service calls was actually a case of premature optimization, and that it was therefor evil and not something you should be doing until it was actually necessary to do so. The speaker of the presentation explained that there is a difference between premature optimization and pro-active performance management. Performance and scalability simply do not come for free, and you have to keep certain things in mind if you want your system to have those qualities.

Now, before i go further, i would like to state that i do believe that clean, simple and reusable code is something that developers should always strive for. I also believe that you should try to limit the number of times you hit the database, or the number of remote service calls you make in a single business transaction. Those goals often seem to contradict each other. There aren’t too many data access layers that allow you to easily perform multiple queries in a single roundtrip while still making sure that each query is reusable in a different context. It gets even worse when it comes to remote services. As you undoubtedly know, a lot of industry experts will recommend that you provide coarse-grained service interfaces instead of fine-grained service interfaces. The upside of coarse-grained interfaces is that they often offer better performance due to less chattiness in communication. Unfortunately, it also often also leads to services that are implicitly coupled against the clients that are known to be using them. With that i mean that many of those coarse-grained services are designed with certain client-characteristics in mind. And shouldn’t services be independent of the clients that use them? This approach typically has an impact on the reusability of those services for clients which are to be developed after the service has already been deployed.

So how do we solve these issues? It’s pretty simple. I want each database query to be reusable in whatever way i need: combined with other queries in a single roundtrip, or executed separately. I also want a fine-grained service interface where i can execute precisely the ‘remote action’ i need, and avoid the chattiness when i need to execute several of those ‘remote actions’ in a single business transaction. The answer is of course: batching of remote operations, whether they are database queries or remote service calls or whatever else that essentially boils down to an out-of-process call.

I really think that every kind of architecture should at least make this reasonably easy to do so. It really doesn’t take that much effort (or in some cases i’d even call it imagination) to make all of this possible. I’m actually pretty lazy so if i can manage to get it done, there’s no reason in the world why you shouldn’t. It can be done pretty easily, and it really doesn’t come with that much of a cost. Of course, writing your code this way takes a little bit more work than doing it the ‘easy way’ (little more being ‘minutes’ vs ‘hours’ though). But then again, if the ‘easy way’ were the right way, we wouldn’t even be talking about performance anti-patterns, right?

For me personally, i’ve gotten to the point where i really couldn’t care less about possibly slow performing code in advance, as long as that code is executed in-process. No matter how good you are, you will practically always guess wrong when it comes to slow-performing in-process code. Just write clean and readable code and if some parts of it turn out to be slow, you just use a profiler and it will quickly tell you which parts are causing the slowdowns. It’s pretty much always the last place you suspect so why bother writing difficult code for parts that probably weren’t going to be a problem anyway. But for out-of-process stuff: be vigilant, because any performance problem related to it could have easily been avoided from the start.

Share/Save/Bookmark

Posted in Opinions, Performance | 2 Comments »

Assembly Partioning Advice

Posted by Davy Brion on 8th December 2008

Patrick Smacchia wrote an excellent post on how you should partition your code in multiple assemblies. Because this is one of those subjects that i’m pretty opinionated about, i figured i’d quickly recap the valid and invalid reasons for creating assemblies that Patrick highlighted.

Valid reasons for creating a new assembly:

  • Tier separation: separating the code you will run in different processes. For instance: having an assembly for client-side only stuff, and one for server-side only stuff

  • Avoid premature loading of large pieces of code that aren’t always necessary: if you put the ‘optional’ code in a separate assembly, that assembly won’t be loaded until you actually need it.

  • Framework feature separation: if your framework offers types that will never be used together (for instance: types for web development vs types for windows development) then it doesn’t really make sense to put them in the same assembly.

  • AddIn/Plugin model: there are many valid reasons for putting plugins in their own separate assemblies

  • Tests: i personally don’t like to put my test code next to my production code, so i always put that in a separate assembly

  • Shared types: all ‘common’ types that you would like to use in different tiers

Invalid reasons for creating a new assembly:

  • Assemblies as units of development: there’s not a single source control management system that doesn’t make it easy for multiple people to work on the same assembly

  • Assemblies as units of reusability: this one wasn’t on Patrick’s list, but it is a pet peeve of mine. I’ve often seen people separate things into multiple assemblies so each part could be reused separately. Which is a prime example of Intellectual Masturbation Syndrome if there’s no actual need to reuse each assembly separately.

  • Automatic dependency cycle detection: when assemblies have cyclic dependencies on each other, Visual Studio automatically notifies you of the problem. Patrick obviously recommends using NDepend to prevent such problems. I’d recommend thinking before/during/after you write the code :)

  • Using internal visibility to hide implementation details: if you want to hide implementation details you can use the internal access modifier so the ‘internal’ parts are only available to the types contained in the owning assembly. I seriously dislike this approach. Using the internal access modifier is often a good sign that there is something wrong with the design. Hiding implementation details is not always the same thing as ‘proper encapsulation’!

  • Using internal visibility to prevent usage from the rest of the code: Yet another approach that i seriously dislike. I prefer to use the Published vs Public approach

Share/Save/Bookmark

Posted in Opinions | 4 Comments »

What It Takes To Be A Great Technical Lead

Posted by Davy Brion on 4th December 2008

Most teams have some kind of technical lead in place. They’re often referred to as the ‘dev lead’, or the ‘lead developer’ or the ‘lead programmer’ or whatever. Some people are great fits for this role, and some simply aren’t. Below is my list of what i think makes for a great technical lead. Note: i’m not claiming that i live up to all of this, although i do try to.

  • You obviously need strong technical skills. You are responsible for the final result, so you better make sure that there is a solid technical foundation for the team to build upon. This doesn’t mean that you should build this foundation entirely yourself. Preferably, you involve your teammates into this as much as possible. You’re also responsible for fixing technical issues that your teammates can’t solve. You either fix it, or when that’s not possible you should figure out an acceptable workaround. Be sure that your teammates are fully aware of the details of the solution or the workaround.

  • You have to be able to teach your teammates. As a technical lead it is your duty to improve the skills of your teammates. No matter how good you may be, if you can’t transfer that knowledge and those skills, you’re not doing a good job as a technical lead. If there are some core principles or practices that you want them to apply to their work, you need to make sure that each and every one of them really ‘gets’ it. You need to be willing to invest the time and effort it takes to achieve that.

  • You need to trust your teammates. This isn’t always easy, especially when it’s about someone who hasn’t progressed as far or as fast as you would’ve liked him to. But it is definitely necessary. If a teammate realizes that you trust him, he will usually respond with improved output. It might not always be everything you hoped for… but either his effort, or the quality of the work will improve. Keep trusting the teammate, and eventually both will improve. Which actually happens a lot sooner than most people would think.

  • Stimulate self-organization. I know a lot of people don’t believe in self organizing teams. And to an extent, that disbelief is somewhat valid. There always has to be one or a couple of people who have some kind of leadership role (be it officially or not). Those leadership roles do not prevent self organizing teams though, in fact, i’d say they enable them. Do not simply assign tasks to your teammates all the time. Organize planning meetings where members can choose the tasks they will do. Make sure there is always some kind of balance though. You really need to prevent that person A always gets the shitty tasks or that person B always get the funnest tasks. Mix it around it a little and try to make sure that the fun/shit ratio is never out of whack.

  • Don’t keep the coolest technical tasks for yourself. If the project requires some kind of technical research to use a new library or to figure out an approach to a new problem or whatever, make sure all of the teammates get the chance to do these kind of things once in a while. It’s not always possible to do so, but when you can, it really pays off. Morale goes up, trust goes up in both directions, and everybody improves.

  • Try to prevent overtime as much as possible. If you’ve been given an impossible deadline, try to convince management that it’s simply not doable. Fight for it if you must. But realistically speaking, you can’t extend every deadline they throw at you, and sooner or later you’re gonna be in a situation where you and your teammates are going to have to put in some overtime to get everything done on time. Don’t tell your teammates they have to do it. Ask them if they want to do it. For some people, this doesn’t always make a difference but for others, it makes a huge difference. And this one is very important when you’re doing overtime: do not go home early while your teammates are still working, because it will come back to bite you in the ass eventually.

  • Remember that you are responsible for the final result. If something goes wrong, it really is your fault. Never put the blame on one of your teammates. Not within the team, and definitely not when managers are present. If a teammate screwed up and the problem made it into the production version, then that is your responsibility and your fault.

  • Give credit where credit is due. If a teammate did a great job with something, give them that credit and make sure everyone else knows about it too, especially management. Never take credit for the work of a teammate because that is simply one of the lowest possible things you could do.

  • Finally, you need to realize that your teammates are not your developers. I’ve often heard technical leads say things like “yeah, my developers…” or “my guys … “. No. They are your teammates, no matter what your role in the team is. Having a leadership role does not mean you are the boss of your teammates or that you can boss them around. If anything, it destroys morale and the results of your team will suffer tremendously from it.

And that’s my list… did i miss anything?

Share/Save/Bookmark

Posted in Opinions | 12 Comments »

Do Not Litter Your Code With Null Checks

Posted by Davy Brion on 2nd December 2008

Just read the following post on the performance of try/catch and throwing exceptions. In the author’s small (and completely unrepresentative of real-world scenarios) performance tests, it showed that throwing exceptions is a quite costly operation.

Ah… if only it were that simple. Throwing an exception is indeed a costly operation, compared to most other statements. But let’s get real… the performance ‘hit’ of throwing exceptions in real-world scenarios is completely negligible unless you’re doing it in a tight loop or a piece of code that is being executed pretty much all of the time under heavy user load. In practically every other case, you really won’t feel the difference performance-wise.

Anyways, because of the perceived performance hit, the author concludes the following:

Code defensively rather than catching exceptions wherever possible.

I’m not entirely sure what the author really means with this, after all there are probably plenty of developers who consider throwing exceptions when something is wrong instead of letting things blow up as ‘coding defensively’. But if he’s talking about the ‘defensive coding’ variant which often entails returning error codes or null references to avoid exceptions, and then checking for those return values all over your consuming code, then i could not disagree more.

I’m probably biased because i once had to maintain a codebase where the authors (to this day i believe they were relics from a C++ museum… and no, i don’t dislike C++ but ‘typical’ C++ programming in .NET is just not ideal) tried to hide exceptions from everyone who used their code because ‘application developers don’t understand exceptions anyway’ (sidenote: can you imagine that? not only did they suck tremendously, they were so arrogant to think they were so much better than ‘typical’ developers). So they had a few try/catch blocks in low-level pieces of their code, and when they caught an exception, they would just return a null reference or some kind of old school error code.

My first problem with this, is that it leads to code which is littered with null checks and the likes. It hurts readability, and i’d even go as far as to say that it hurts maintainability because it really is easy to forget a null check if you’re writing a piece of code where a certain reference really should never be null. And you just know that the null checks will be missing in some places. Which actually makes debugging harder than it needs to be. Had the original exception not been caught and replaced with a faulty return value, then we would’ve gotten a valuable exception object with an informative stacktrace. What does a missing null check give you? A NullReferenceException in a piece of code that makes you go: wtf? this reference should never be null!

So then you need to start figuring out how the code was called, and why the reference could possibly be null. This can take a lot of time and really hurts the efficiency of your debugging efforts. Eventually you’ll figure out the real problem, but odds are that it was hidden pretty deeply and you spent a lot more time searching for it than you should have.

Another problem with null checks all over the place is that some developers don’t really take the time to properly think about the real problem when they get a NullReferenceException. I’ve actually seen quite a few developers just add a null check above the code where the NullReferenceException occurred. Great, the exception no longer occurs! Hurray! We can go home now! Umm… how bout ‘no you can’t and you deserve an elbow to the face’? The real bug might not cause an exception anymore, but now you probably have missing or faulty behavior… and no exception! Which is even more painful and takes even more time to debug. That original exception with the stacktrace sure sounds appealing now, doesn’t it?

Btw, why is it that the kind of developers who avoid certain language features because of ‘performance problems’ (usually based on faulty information) are often very likely to make mistakes such as remote calls in loops, memory leaks due to lousy event handling schemes, or my personal favorite: writing a HighPerformanceTimer class which uses Windows API’s because ‘it times much more accurately’ and then in the same class, walking down the stackframe at runtime to figure out where the HighPerformanceTimer instance was called from for ‘easy logging purposes, dude’

Well like i said, maybe i’m just biased…

Share/Save/Bookmark

Posted in Opinions | 7 Comments »

ORM Is NOT Inherently Evil

Posted by Davy Brion on 25th November 2008

There were some comments on a previous post about how the problem described in that post is somehow typical for applications that use ORMs. I really could not disagree more.

It seems that even today, in 2008 mind you, we still have a lot of people who are convinced that ORM usage can never be as efficient as the more classic data access approaches. Now, i don’t even want to get into the whole debate about where business logic belongs (but if you think it belongs in the database you no doubt have better things to do than reading this blog), but one thing that does bother me tremendously is that a lot of people discard ORMs because they simply don’t know how to use it properly.

An ORM is a tool. Nothing more, nothing less. Well, it is a pretty powerful tool and, as with any other powerful tool, improper usage of said tool can really cause a lot of problems. Should we discard the tool because a lot of people never took the time to figure out how to use it properly? That would be kinda stupid, no?

It seems to me that a lot of people seem to have this misconception that using an ORM essentially leads to data-fetching in tremendously inefficient manners. They see the tutorials where only the ‘get-by-id’ functionality and the lazy loading features are shown and they somehow think that’s all there is to it. They hear all the horror stories about projects that performed terribly because the developers used an ORM and they blame the tool, not the developers. Nevermind the fact that there are plenty of projects that use more classic data access approaches who perform like shit as well.

So let’s try to get a few of these misconceptions out of the way, shall we?

  • You can create highly efficient queries with an ORM tool, and you can actually do so in a manner which enables high developer productivity
  • ORM’s are not slow by definition. Using them wrong (just like with any other data access technology) can be tremendously slow however. Who’s at fault?
  • ORM’s do not use a shitload of memory. Improper usage of them however can lead to excessive memory usage. Blame the developer, not the tool.
  • ORM’s do not lead to lazy developers, who are doing lazy coding by relying on lazy loading. Bad developers lead to lazy coding by relying on lazy loading.

So, for those who think that ORM’s can never work ‘right’, i have only one question: are you absolutely sure you know what you’re talking about?

Share/Save/Bookmark

Posted in Opinions, Rants | 8 Comments »

Why On Earth Would A Developer Do This?

Posted by Davy Brion on 22nd November 2008

I just saw the following piece of code:

        public void Execute()

        {

            ArrayList empIds = PayrollDatabase.GetAllEmployeeIds();

 

            foreach (int empId in empIds)

            {

                Employee employee = PayrollDatabase.GetEmployee(empId);

 

                if (employee.IsPayDate(payDate))

                {

                    DateTime startDate = employee.GetPayPeriodStartDate(payDate);

                    Paycheck pc = new Paycheck(startDate, payDate);

                    paychecks[empId] = pc;

                    employee.Payday(pc);

                }

            }

        }

The code is old, pre .NET 2.0. But no, the usage of the ArrayList isn’t what bothers me here. It first gets all of the Id values for all of the employees in the database. Then it loops through the list of Id values, and fetches each employee from the database. Whenever i see this kind of code, it makes me want to kick the person who wrote it.

In case you don’t know what is so bad about this, think about this: if you have 5 employees you first send one select statement to the database to get their id values. Then you send another 5 select statements to the database to get the data of each employee. Oh well, 6 queries isn’t that big of a deal right? It sure as hell is if you could’ve just as easily gotten all of the required data with one query (and only one expensive roundtrip)! Imagine you have to calculate the paychecks of 100 employees instead of 5. How about 1000 employees?

What i really don’t understand about this is that this kind of code gets written every day. Do these people simply don’t care or do they genuinely not know how bad this is? If they don’t know, that’s truly sad. If they don’t care, that’s even worse because a developer who knows how bad this is but still writes it, obviously takes no pride at all in his/her work and (IMO) has little respect for the code, the team, the company and the client.

In case you’re wondering where i saw this code… it’s in Robert C. Martin’s Agile Principles, Patterns, and Practices in C# book. Yes, the Robert C. Martin, aka Uncle Bob. I probably shouldn’t criticize such a well known figure in the OO world, but seriously Bob, what were you smoking? The purpose of the whole book is to teach people how to write good code and there is tremendous amount of valuable information in there. But putting code like this in your examples is really inexcusable.

Share/Save/Bookmark

Posted in Opinions, Performance | 34 Comments »

Agile Development Going Downhill?

Posted by Davy Brion on 17th November 2008

James Shore (author of the fantastic book: The Art Of Agile Development) wrote a very interesting post on his blog: The Decline And Fall Of Agile. You should definitely read it.

I’m afraid i agree with James. Over the last few years i’ve heard a lot of people saying they were doing Agile development, where in reality they hardly were. To quote James:

But guess which part people adopt? That’s right–Sprints and Scrums. Rapid cycles, but none of the good stuff that makes rapid cycles sustainable.

And this is unfortunately very true. A lot of teams are working in short iterations now, and a lot of teams are doing daily meetings, or scrums, or stand-up meetings. But how many of them are actually committed to the technical practices and principles that enable successful Agile development? Honestly, i’ve never seen one.

I’m a big fan of true Agile development but even in my current job, my last 2 teams haven’t done it ‘completely right’ either. Our results are pretty good though, but i think we can still do much better. I gradually try to introduce more of the principles and practices but it does take some time. But all of these misconceptions about Agile Development that so many people (developers, project managers, management in general) have aren’t really helping. At my current job, those misconceptions are pretty small and they don’t really have a bad influence. In previous situations at clients, i did notice how those misconceptions led to tremendously ineffective situations. Which is pretty sad actually, because sooner or later managers will probably become skeptical of Agile Methodologies. If that leads to people abandoning some of the technical practices and principles, it would be a pretty big loss to the ’cause’.

All in all more reasons to read James’ excellent book i think. If i could legally get away with forcing people to read that book, i would :)

Share/Save/Bookmark

Posted in Opinions | 3 Comments »

Career Advice For Young Developers

Posted by Davy Brion on 25th October 2008

Over the past few years, i’ve seen a few young developers make some not-so-smart decisions about their careers and futures. I’ve always found situations like that frustrating because i hate seeing good developers make bad choices. So i decided to write down a bit of career advice for young developers:

Make sure you like doing your job

To me, one of the most important parts of a job is the fact that you should enjoy doing it. If you do the math, you’ll quickly realize that you’ll spend somewhere around half of your active adult life at your job, so you might as well try to make the most of it. If you’re unhappy or frustrated at your job, you’re essentially wasting a large part of your life so you’re better off trying to find something that you actually enjoy doing.

Make sure you get satisfaction out of your job

A lot of people want different things out of their job, so it’s hard to quantify those. For some people it’s really important that their work is actually useful or helpful to others. Other people might get more satisfaction out of the fact that they are continuously increasing their skills. Other people want to make sure they work on very profitable stuff. Whatever it is that satisfies you in your job, make sure you get it. It keeps you motivated, it keeps you sharp and it helps in keeping you happy in general. Keep in mind though that there will always be days or short periods of time where you don’t feel like you’re getting that satisfaction out of your job. It’s only natural that this happens once in a while, but if you feel like that on a regular basis, you’re probably better off looking elsewhere for something that suits you more.

Choose between actual jobs, not companies

If you have to choose between jobs, go for the job that seems the most interesting and fulfilling. Do not base your decision on the actual companies offering the jobs. Always keep in mind that there are plenty of developer jobs out there (especially if you’re good) so you don’t really need to focus on stuff like job security. This can be different if you already have a family to feed, but then again, this advice is targeted to young developers. Go for the job that interests you the most, it will usually enable you to grow as a developer and increase your skill level substantially (which in the long run is the only true way to achieving job security anyway… more on that later).

If you like developing software, then keep working as a developer!

Developers that start working for larger companies often feel the need to climb up the corporate ladder to achieve some sort of management job. Because managers are important right? If you want to make it into management, you better be very sure that it’s really something you want to do. Be prepared to be stuck in meeting rooms with people who often don’t really know what they’re talking about and are often only interested in advancing their careers, even if that means if it has to be at the cost of others. If you’re a good developer and you like developing, there’s absolutely nothing wrong with staying a developer. There are far too few good senior developers, and those people are always in heavy demand.

Don’t put up with being a Code Monkey

Some developers are often considered as Code Monkeys, and they don’t really get a lot of respect. Those developers can be just as valuable as any other developer, so if you ever feel like people look at you as just a Code Monkey, there’s no reason to put up with that. You’d be better off finding a job where the developers are treated and appreciated as the valuable resources that they are.

Learn from your co-workers

Make sure you can learn from the people you’re working with. If you’re stuck in a place where you feel that you aren’t learning anything new from your co-workers, you can quickly become demotivated, which is a terrible way to spending large parts of your days. A job where you frequently learn new things from your co-workers is really a blessing. Not only are you getting better at what you do, you’re basically getting better for free, without having to invest your personal time into it.

Keep up with new technologies and ways of working

As i just mentioned, it’s very important that you learn from your co-workers. But that doesn’t mean you shouldn’t spend a bit of your own time into improving your skills. You don’t need to spend hours a day outside of work on getting better, but a couple of hours here or there could really make a big difference into increasing your skills. Not only do you get better from it, it also enables you to improve the skills of your co-workers, which in turn makes you a more valuable developer. Learning from people is important, but allowing people to learn from you is just as important.

Don’t focus on job security

I used to work at a large company in the financial industry. I was there as a contractor, so i wasn’t a ‘real’ employee of the company. I did meet some young developers there that only started working there because it was a large company where they had job security and a chance to build a career for themselves. The thing is though, those large companies usually aren’t a very satisfying place to work. Things take a long time to get done, and the bureaucracy alone is enough to drain you mentally after a few years. If that happens, you’ve probably found other ways to get some satisfaction and happiness out of your life, usually outside of your work hours. Odds are that you haven’t really invested much in your technical skills, and before you know it, your skills are pretty much outdated, and you become less attractive as a potential hire for other companies. At that point, you’re pretty much stuck at a crappy job. The job security you wanted at first is there, but you’ve lost a lot of options for you personally and you’re now stuck in a crappy job. If you want long-term job security, the best way to achieve that is to just make sure that you’re very good at what you do, and that you love doing it. If you’re a great developer, you will always find a great job somewhere. Yes, even when things in this business aren’t going too great. Great developers will always be in demand.

Don’t let money dominate your decisions

I’ve seen promising developers leaving their jobs just so they could make more money somewhere else. Now, if you’re sure that you’re going to like the new job more, then you’ve obviously made a good choice. But it’s important to be careful. You can always make more money somewhere else, but you often don’t know what kind of crap you’ll have to put up with to get that extra money. If you let money be the deciding factor, you might end up in situations where the only benefit of the job is the paycheck. If making money is your only goal in life, then you probably don’t mind too much. If you want to enjoy your career, you’re probably better off choosing the interesting jobs over the higher paying ones.

Always make sure you can leave your job if you’re not happy there

A lot of companies offer nice benefits to their employees. Some of those benefits could tie you into the company for the long term and you should be careful about those. No matter how much you like a job, one bad management decision could change everything. If something like that happens, and you suddenly aren’t happy in your job anymore, it really would be a shame if you feel like you can’t leave due to financial consequences of having to drop those benefits. Financial institutions are especially good at this… they typically offer employee benefits for their financial products, and if those products (like a loan for a house) tie you into the company for a long time (like, 20 years or so) it might become hard to leave that job due to the extra money it’ll cost you. Make sure you don’t get caught up in a situation like that, and make sure you become great at what you do. If you are great, you’ll usually end up with more financial flexibility anyway ;)

In conclusion

I’m not going to claim that the advice outlined above is a guaranteed way of having a successful career as a software developer. Most of it is entirely up to you and the amount of work you’re willing to put into it. I do think that the advice above can definitely help you avoid some bad situations that could otherwise sneak up on you.

If you want to add some advice to the list, or think i’m wrong about something, be sure to tell us in the comments :)

Share/Save/Bookmark

Posted in Opinions | 38 Comments »

Beware The Evils Of Code Generation

Posted by Davy Brion on 22nd September 2008

We have this rather large project at work, one that’s been in development for a few years now. This project has had many releases already, and from a business perspective, is quite successful. From a technical point of view, there were definitely some things that could’ve been better. The largest problem is that this project uses a very extensive code-generation process. This code generation process basically retrieves all of the database metadata and generates an entire Data Access Layer (based on basic ADO.NET), a shitload of automated tests to cover that entire DAL, a whole lot of extra classes which form a data-driven business layer (real business logic can still be added though), and again, a shitload of automated tests that cover the data-driven business layer.

Now, the people who originally came up with the code generation obviously had good intentions in mind. They wanted to maximize developer productivity so everyone could implement the required features as fast as possible. And that’s pretty much the reason why people turn to code generation: to increase productivity. Code generation however, is not a good way to do that. In the short term, it definitely increases productivity though. But it comes at a terrible cost: an incredibly large technical debt. The thing about code generation is that it’s basically a shortcut. When it comes to developing software, each shortcut brings some kind of technical debt with it, and sooner or later, you have to pay off that debt, or risk having your knee caps shattered (why yes, i am watching my Soprano DVD’s again!).

Now, the technical debt you incur by implementing a certain feature in the quick-n-dirty way instead of doing it properly from the start is in most cases small and easy to pay back if you don’t put it off too long (obviously, it’s best to simply avoid having to incur any technical debt in the first place). Generating an incredibly large library of code, and then using that code all over the place has an impact that you simply can not recover from when the project has been in development for a long time. If you want to make serious changes in your generated code so you could, for instance, reduce coupling to concrete classes, you may be in for a rough ride.

In our case, most of the things you could do with the generated code could be done in more than one way. Every possible usage scenario was being used at least somewhere in the application’s code base. And not just in a few places, but pretty much all over the code base. This made it pretty much impossible to make changes in the templates that would be used to generate the code, which would introduce compiler errors at least somewhere in the system. And not just a few of them, hundreds of them. Sure, you could start fixing them. And then you could start on your next change in the templates, and it would lead to a few hundred more compiler errors. If you’d simply have to change a bit of syntax here and there, it would be painful, but at least it wouldn’t be something you couldn’t overcome. But if you want to change the behavior of the generated code, you’re in pretty big trouble. All of the code that uses the generated code expects certain behavior to occur. Changing the templates would mean changing a lot of the real code.

When you’re in a situation like this, Michael Feathers (author of Working Effectively With Legacy Code) can’t even help you out. Hell, even Batman would run away like a frightened schoolgirl. Which is basically what we did too. We decided to leave the generated code and the real code as is for now, and we came up with a new architecture (with no code generation) which we’re going to use to develop the new functionality. The old code will slowly be migrated to the new architecture whenever we have room to do it, or whenever we need to make serious changes. It’s not perfect, but starting completely from scratch is an approach that wouldn’t make a lot of business sense anyway, and you have no guarantee whatsoever that the ‘new’ system will actually catch up with the ‘old’ system in a timely manner.

I think this serves as a nice example of how a code generation based approach can really come back to bite you in the ass like Jaws with a vengeance. Everything you gain in initial productivity costs you a lot of flexibility in the long term, which (also in the long term) ends up costing you more productivity than you ever gained in the first place.

Always keep in mind that code generation is usually a solution to a problem that wasn’t solved properly in the first place.

Share/Save/Bookmark

Posted in Opinions | 19 Comments »