I have been a software developer/computer programmer for almost 7 years (mostly .NET and C#), and I've just been reading the appendix on Service Orientation in Juwal Lowy's excellent book Programming WCF Services, Second Edition.

The above led me to the Wikipedia article about SOA, and the Software Engineering category links at the bottom, incorporating various fields (e.g. Requirements Analysis), concepts (e.g. Data Modeling, Structural Analysis), models (e.g. Agile, UML), orientations (e.g. Aspect-Oriented) and people (e.g. Martin Fowler, Grady Booch).

I have come to the realisation that I may have some experience as a developer but very little as a "software engineer". Sure, I continue to run into many of these concepts in my day-to-day job, but not always in great detail.

My question is how I can become an expert in the "engineering of software", and more specifically:

  • What are the most important concepts and disciplines for me to focus on to become a good software engineer?

  • What are the best resources I can use to train myself as a software engineer (as opposed to a developer/programmer)?

  • What type of projects/jobs can I focus on to become a software engineer?


I have the following commandments in my bookmarks and read them from time to time:

The Ten Commandments

What we need is a set of rules or guidelines to help developers keep themselves (their egos, actually) separate from their code. Hence our Ten Commandments for Egoless Programming, which you can also download in handy "stone tablet" format:

  1. Understand and accept that you will make mistakes. The point is to find them early, before they make it into production. Fortunately, except for the few of us developing rocket guidance software at JPL, mistakes are rarely fatal in our industry, so we can, and should, learn, laugh, and move on.
  2. You are not your code. Remember that the entire point of a review is to find problems, and problems will be found. Don't take it personally when one is uncovered.
  3. No matter how much "karate" you know, someone else will always know more. Such an individual can teach you some new moves if you ask. Seek and accept input from others, especially when you think it's not needed.
  4. Don't rewrite code without consultation. There's a fine line between "fixing code" and "rewriting code." Know the difference, and pursue stylistic changes within the framework of a code review, not as a lone enforcer.
  5. Treat people who know less than you with respect, deference, and patience. Nontechnical people who deal with developers on a regular basis almost universally hold the opinion that we are prima donnas at best and crybabies at worst. Don't reinforce this stereotype with anger and impatience.
  6. The only constant in the world is change. Be open to it and accept it with a smile. Look at each change to your requirements, platform, or tool as a new challenge, not as some serious inconvenience to be fought.
  7. The only true authority stems from knowledge, not from position. Knowledge engenders authority, and authority engenders respect?so if you want respect in an egoless environment, cultivate knowledge.
  8. Fight for what you believe, but gracefully accept defeat. Understand that sometimes your ideas will be overruled. Even if you do turn out to be right, don't take revenge or say, "I told you so" more than a few times at most, and don't make your dearly departed idea a martyr or rallying cry.
  9. Don't be "the guy in the room." Don't be the guy coding in the dark office emerging only to buy cola. The guy in the room is out of touch, out of sight, and out of control and has no place in an open, collaborative environment.
  10. Critique code instead of people?be kind to the coder, not to the code. As much as possible, make all of your comments positive and oriented to improving the code. Relate comments to local standards, program specs, increased performance, etc.

Perhaps it won't make you a better craftsman (or woman), but reading them (and trying to abide by them) doesn't make you a worse one either! :)


There are some disagreements I've see with respect to what a Software Engineer is in the software development community. Agile proponents in particular seem to think of Software Engineering as a construct of the Waterfall methodology. On this I disagree.

In my opinion, a Software Engineer is somebody who designs, builds, and tests software and puts pretty much equal weight on all three areas. If you jump right into code without a thought for the overall system or for testing your code, you're not a Software Engineer. If you design and build code, but don't bother with testing, you are not a Software Engineer.

To that end:

The most important concepts and disciplines you can focus on are design and test; odds are you already know how to program. Focus less on design patterns themselves and more on the reasons why they exist in the first place. Learn the SOLID principles. Learn how to write automated unit tests. Learn how to use test doubles effectively in your unit tests.

You've already listed two great resources; I worship at the alter of Martin Fowler. I'd add Robert Martin to your list, and I've already to linked him. Read his books, they're great. If you can ever attend one of his talks about pretty much any development subject, GO. The man is a firebrand.

Buy a few books authored by those two, read and grok them, and you're probably well on your way to becoming a great engineer.


sed 's/Developer/Engineer/g' cv.tex


I think the difference between "Software Engineer" and "Software Developer" is largely semantic. One could argue that it is a difference in education and training. "Software Engineer" might be best applied to a person with an engineering degree in Computer Science. "Software Developer" is, in my experience, a more general term to describe someone who develops software, either professionally or as a hobby.


The only way to become an expert in anything is by doing it. Expert status takes time, and more importantly, constantly being faced with new situations. Obviously if you do the exact same thing for 10 years then you really only have 1 year of experience.

That said, the difference between a "software engineer" and a "software developer" in most places is simply the title. Because we don't have a licensing board or anything that most other professions have then there is zero control over those titles.

Which means your question translates to: "How do I become an expert developer?"

In this case you need varied experience using a variety of tools and languages to do the job. You should start playing with different system designs (architecture) in order to understand the choices available to you. You should also get in front of the end users / business analysts in order to understand requirements gathering.

The best resources available to you are going to be your peers. Not just the people who are doing the same thing as you, but your boss and everyone else you can interact with.

As far as types of projects, it doesn't matter. Anything from building marketing websites to full blown SaaS applications can teach you something. The trick is to think about what you are doing, why you are doing it, and how it can be improved. This includes the entire application (from it's purpose to usage) to individual components (object models, etc).


As others have alluded to, the terms "developer" and "engineer" are very overloaded in this industry. Ask 10 different people to define them and you'll get 10 different answers. Throw the term "software craftsman" into the mix and you'll get 10 more :)

In my experience, you are a software engineer if you:

  1. Apply critical thinking skills as you write and evaluate code. Are you only trying to solve the problem at hand? Or are you also thinking about the clarity, readability, and "intention-revealing-ness" of code as you write it?

  2. Are constantly sharpening your saw. A software engineer realizes that this industry is moving at an insane pace, and that a professional engineer must actively work to keep up.

  3. Can reason about software systems and architecture at a macro level as well as a micro level. If your job never makes you think beyond one or two classes or methods at a time then you're a developer, not an engineer.


I tend to associate 'Software Engineering' as the big picture view of Software Development... this can include requirements, documentation, business logic, testing practices, development processes, even stuff like marketing. It is more of a business-oriented view of the development process.

That said, I work as a 'Software Developer' and have made requirements documents, done testing, and had to make business logic decisions. The specific title will mean different things to different people. I think the smaller the IT/programming department at a company is, the more of these responsibilities are likely to overlap with the actual code-writing process.

Also, I second (third?) the recommendation of Martin Fowler - very down-to-earth, helpful, and easy to read. :)