Ten Commandments Of A Software Engineer


Published on

Software engineering is not an easy profession. You have to constantly learn new things to improve your coding skills and make sure you produce better and cleaner code over time. It's not difficult, but you have to be aware of a few basic principles. With them in mind you will feel a better engineer and will gain respect from your fellow engineers. And the Lord said: "Thou shall always remember to write unit tests - no matter the deadline. Remember to keep the build green. Thou shall commit often and with meaningful messages (...)"

Published in: Technology
1 Comment
  • As to disrupting legacy systems: An on-line vendor asked me to do minor upgrades and keep his system running. However, his main problem was not addressing huge security holes that previous 'professional amateurs' had left in as debug statements. The system was, indeed, a bramble bush.

    Since he had no version control, The time honored rule of 'you touch the code, you own it' meant I was in for a heap of abuse. -- This was one legacy system that created huge liabilities for everyone involved.

    I still wish this vendor well, but his headlights were just not turned on, so I fired this boss with prejudice.
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Before I start, let me introduce myself. My name is Sebastian Marek. I am Polish, but I live in Sheffield where I've settled over 6 years ago. I've got over 12 years of experience in software enginering, I have written programs in Visual Basic, Pascal, C++, Java, Python and PHP. I have written 2 books about developing LAMP applications with my close friend, but they're in Polish so I don't think they will be any use for you guys and also published couple of articles in php-arch about git - a distributed version control system and Sonar - a continuous inspection tool. Automation is what I love - starting with automated testing, integration and deployment and finishing with process automation.
  • Initially I wanted to do this talk in a religious tone, talk about commandments and crossing Red Sea and so on, but then I thought, wait a minute, I am gonna be in Scotland, in Edinburgh, at WiskyWeb conference sipping first class whisky.So I put use these barrels to help me walk you through the commandments, but then I thought, you gonna get drunk too quickly and nobody will listen to me.
  • So I think going slowly, in small chunks, or let's say shots, will be the best way to go. I have picked up the 10 most interesting and most important things in my opinion. I do realize there are easily dozens of different engineering principles that you should bear in mind and follow, but we could spend long hours talking about it. And what I want to achieve today, is some sort of base, a topic we could talk about during and after conference and share our experiences.
  • So if you find at least 2 things that are worth remembering and using when you get back to your keyboards I will consider this talk to be successful. I will be talking about all sort of things, some general principles about developing and maintaining software systems, about why testing is so important and will finish up with some not so technical advice.
  • But I will start very technical. Thou shalt not disrupt the legacy system. A dilemma that we all have to face sooner or later. I guess "later" is more convenient thou. You have to think that through really carefully.
  • First of all remember that these old systems are probably the most important systems in the company. They've been written ages ago using obsolete technologies, but they still work and are probably constantly heavily used. Some of them might be business critical and essential for normal business functioning. Very risky to change, even a small bug can trip them over and cause a lot of problems. They're poorly documented and very hard to test. Nobody really understands them. Developers hate them, business love them! So what can you do in this case? You have to fight the temptation to refactor it! A short prayer will help, but a shot or two whisky shots are equally good.Step back and think. When was the last time this system was touched - changed/patched/improved? Is there a lot of other system components depending on it? Does the system do itsjob? Is this system well documented or is there enough expertise in your team that you can rely on? These are basic questions, but hopefully you can see where I am going with it. If something is not touched at lot, then there is probably a very limited value in changing it. On the other hand, if the system is heavily patched and constantly causing problems, well it's probably broken already and doesn't do its job. Refactoring is in your best interest.If it's a core component of your system it might be very, very risky to change it. Think whether it is worth the hassle as new system might not be successful or might not meet business requirements. If it's not documented or the original team that developed the system is no longer working with you, the risk is even higher as you will have a very limited knowledge about the possible implications of your decisions. That doesn't mean you shouldn't try to refactor such a system. It’s expensive to replace a legacy system, but it is also expensive to maintain it. You just have to see what is more beneficial for the company, and not short term, but long term.
  • So how can you approach such a system. First of all, try to identify small independent parts of the system and blackbox it. Understand it well, make sure it work the way you expect it work, clearly define the responsibility of it, and what is its input and output. Hide behind an interface - this way you will be able to slowly replace the old implementation. John Mertic will tell you more this afternoon about his experience with legacy codebase and challenges that come with it.
  • How many times did you write the same code all over again? And I am not talking about simple duplications now, I'll touch on that later on.
  • I am talking about simple and repeatable operations - sending/receiving HTTP requests, opening/reading/writing files, interpreting cli arguments, etc. What about MVC pattern? How many of you have written your own framework and most importantly - why? Have none of the existing ones met your requirements? Have any of them lack any specific feature? Tweet me or talk to me afterwards - I'd really like to know. What I will do now, I will try to convince you why you shouldn’t do it. If you encounter a problem or you are asked to implement a feature, go and spend some time first and find out, whether somebody else haven’t solved it for you already!Writing yet another framework, cause you know better, will most probably not end up good. This is very short-term thinking. Why not instead try to write this missing feature and contribute it back to an existing framework? In-house support is expensive, but if you get it included in one of the open source frameworks, you will get many more eyes looking at the thing you're trying to implement. You will also get support from open source community. No more single point of failure in your company, cause this one super framework is really something only you know the best. Let me guess, it is also not very well documented… So when a new starter joins your team it's much harder (and more expensive) to spread the knowledge. It is so much easier to find somebody who already knows the framework you're using and have dozens (if not hundreds) of developers helping you when you're stuck. Instead of these 2-3 people in your company who are constantly busy. How long did it take to stabilize your framework and fix the bugs you've left behind you. I bet you don't have enough time to properly maintain your framework. And if you do, have you ever thought how much does it cost you to support it? It is so much cheaper to contribute back and use the power of the whole team behind the framework to help you out.
  • Oh my favourite one. How many of you don't use a version control system at all? What do you use - CVS, Subversion, Git, Mercurial, Bazaar, BitKeeper? Is your version control system slowing you down?
  • The problem I have with central VCS like CVS and Subversion is I can't use all benefits of feature branches. I prefer to develop new features using branches without disrupting the main development branch. I also often want to make my branch available for others so they can give me some feedback before I merge it back into the main development stream. That's why I love so much distributed vcs. I can have as many branches as I want and control what others can see. This way I can commit often and save the state of my repository so I don't loose it. Verbose commit messages help me with documenting the progress of my work. How often do you commit your changes? Once a day, twice a day, every few hours, every hour, every 15 mins? On average I commit once an hour (obviously depending on what I am doing at the given time), but it also happens I commit my changes a few times during an hour. And once I am happy with the result I squash all the commits to the size I am comfortable with - I maintain the changes, but I alter the number of commits and messages that come with them. That's what I love in git - the flexibility and power. And when we talk about commit messages it is extremely important that you form your commit messages right. I am often asked how verbose should I be when writing commit messages, and I always respond the same way. Think about coming back to the code you're committing several months later, maybe half a year later, and if you can't understand from commit history what changes have been done and why, then your commits are not verbose enough. People often don't care, because it's usually somebody else that has to do it for them. So they don't appreciate it.
  • I think this is one of the things software engineers are not really good at. Writing documentation is often left as the very last part of a project. And this is one of the main reasons why it never gets done properly!You have to move on to do your next project and this is always more important then writing or finishing documentation for something that is already released. Even if you start working on it, following your project plan, you also want to move onto some new, cooler things, and not work on something that you worked for the past few months. It's boring… right?
  • So what can you do to improve your documentation skills and to make sure that when the project is over you have it all well documented? I'd say it's very similar to the concept of TDD, write your documentation upfront or as you go along when writing the code. If you leave until the very last minute,at the end of the project, I can guarantee, you will forget why some things were done one way or another, or you will forget to document some parts of the system altogether! There are 2 different type of documentation - the internal one for developers, and external one for customers and users. Creating documentation for other developers is easier then you think. For different languages there are different solutions, but all of them work in the same way - you use code comments and annotations to describe your code. Then run a parser that will search and analyze this comments and spit out the documentation for you! It is as easy as it sounds! But, it's just a start. As a developer I would expect a few more things in the developer's documentation. And this is: practical examples how the code or API should be used. This way you can show how you intended the code to be used. Some of you will probably shout at me right now saying - but the code should be self explanatory! And this is true, I couldn't agree more, but there are usually a few ways of achieving the same goal, and not all of them are equally efficient or right. So help developers and let them know the best way you code can be used! Real world examples are the best! Also, I find myself writing something that is later on expanded by the other members of the team. It also happens quite often that they did not work with me on the project and did not participate in the upfront design, so they don’t really understand my intentions. So it's also very important to document how specific part of the systems where designed and explain the initial requirement. Hints and tips about how the code can be developed further, enhanced and improved are especially useful and important. This way you can avoid a situation, when somebody else joins the project and does not follow the original design! Believe me, it actually happens quite often. End user documentation is a bit different. This usually documents the UI, how the end product can be used - it's a manual. Its purpose is completely different, but equally important! If you deliver something for an external customer, well this is usually part of the deal, and they will not accept the software without the manual. If you deliver something internally, well it tends to be a completely different story. People try to save time and provide only bits and pieces of documentation and then complain that the new system is not used properly. It's quite obvious, but often forgotten. You're doing yourself a favor by documenting the system well - this way you will avoid the end user hassling you all the time asking how something can be achieved and raising a ticket in your bug tracking system telling you that something doesn't work as it is suppose to work or that certain feature is actually missing (despite the fact the it was originally de-scoped). You will only save your time long term writing high quality documentation.
  • Quality Assurance. Testing. Expensive. Time. Not enough. Sounds so similar to creating documentation. Often not appreciated enough. Often limited. Often not effective. Because some people don't understand how to do it properly and how important it is. Testing is also often linked to a manual process. Cause you have to start the software and check whether it works the way it was intended to work, and whether all the features and requirements were delivered. And these people couldn't be more wrong.
  • So let's get back to the basics. It costs significantly more to fix a bug at the end of the project that it does to fix the same bug earlier in the project. So do whatever you can to integrate and test your software at the early possible time. So how can you do it? As a software engineer - do not doubt in the power of unit tests. This is the most powerful tool that you have. Don't hesitate to use it. And do it right. Don't just do it because you were told to write the tests. The test will allow you to prove that your code works the way it is suppose to work. Don't write the tests for the sake of the test. In my opinion it's better to have no tests then have very poor or broken tests. At least you will not fool yourself and pretend everything is fine. As a software engineer and as a QA engineer create and use functional tests. Automate all the manual testing that you've been doing so far. Tools like cucumber and all sort of ports to other languages will save you so much time. And money! Pick up the most important tests and create regression packs to confirm at any point that all the systems you really care about are still working correctly. As I already said integrate early and often. Pick up any problems at the early stage and fix them. If you integrate at the late stage of development process you will only create more work for yourself and set yourself up for a failure - your project will be either late or very buggy and unstable. If you don't have a continuous integration server, go and set it up. It's easy and will help you so much. If you already have a CI server, don't let any build go red. This will only cause you problems. Red always means broken - either your software or the integration process or the tests. Don't let the noise to distract you. If something is broken fix it. And I mean fix it, not hack it, not patch it just to make it work - fix the root cause, not the symptoms. Sooner or later, if you don't fix the problem properly it will hit you back - in your face. And it will hurt. And if you see a problem - report it, prioritize accordingly and get it fixed. Don't assume somebody else is gonna spot it and do it for you. The longer an issue stays unsolved the harder it will be to fix it later. Don't avoid it, it will not disappear just like that. Somebody needs to fix it. So why not you.And finally be a grownup developer and take responsibility for the code you're working on. Don't let it rot. Look after it, make it work properly and if bugs start to attack it - kill them. Kill them all. Don't hide them under the carpet. They will crawl back as mutants and it's hard to deal with mutants.
  • Oh this is hard. It is.
  • I have seen so many people over-engineering things. Including myself. It is mainly because engineers try to be clever and try to predict what they will need in the future. And that is the problem. A monster is created that is hard to maintain. And you probably use about 60% of its features. Just because you "might" need to do something with it in the future. Understand your requirements early and design your systems upfront. Then you will know what you need. I know it's easier to say then execute. But, if you don't tight yourself up to a particular solution to technology, it will not be a big problem to change it or extend later. How many of you have heard of "Convention over configuration" design paradigm? Make your code simple, but allowing developers to follow a specific convention. I love systems the are straight forward to set up and use because it is so easy to guess what you have to do to make it work. New engineers will pick up and understand the system very quick. Using the same convention across different systems it will be easier to understand them. No more time wasted trying to guess how this bloody system works.
  • Don't over complicate things. Make it simple, stupid! Complex problems are best solved using simple solutions. Albert Einstein once said - "Make everything as simple as possible, but not simpler". This couldn't be expressed better. There is a few things that you can do to make your code simple. First of all modularize your code. Keep the modules small and simple. Let them do only one thing. Single responsibility principle is the key here. And this apply at every level of you system, whether it is a class, a library or a module. Which leads me to the next commandment…
  • Anything that you do to make code hard to read, hard to understand or hard to change will be like shooting yourself in the foot. And dying slowly. After all, sooner or later you will most probably have to come back to that code and make some changes. It is also not all about yourself. Some of us work in teams, sometimes quite big. And then you're shooting at your mates feet. Now that's cruel. And nasty!.
  • So what can you do to get back on track, stop killing each other and increase maintainability of your code? First of all stick to a coding standard. For some it seems to be a total waste of time, but the bigger the code is and the bigger the team you're in is, the harder is come back to the code you or somebody wrote and read it and understand it. It's another side of the convention principle. Follow a convention, so everybody else can easily read your code. So YOU can read your own code. And it doesn't really matter what the coding standard is. To be honest there is as many coding standards as developers in the world. That's why you need one that everybody can stick to. Hopefully all your developers are team members and will stick to the chosen coding standard. If you have problems with it, then you can use some automated tools to make sure everybody is using the chosen standard and beat them to it.Secondly, don't overgrow your modules, classes and methods. There are certain code metrics that will help you asses the size of your code and see whether they are too big. The bigger they are the harder it will be to understand them and therefor maintain them. Different code metrics will tell you about complexity of your code. Keep the complexity under control. Too complex classes and methods will affect maintainability. Finally clean up after yourself. There is nothing worse then leaving a mess after yourself. And by mess in this case I mean dead code. The longer you leave dead code in your codebase the harder it will be to remove it. The harder it will be to understand the code and the harder it will be to change it as you will have limited knowledge about how the code you think is dead will affect the rest of the codebase. So, at the time you deprecate or make a feature obsolete document it well, plan dead code removal and execute it. While it might appear as a low priority task at the time, it will make your life harder and harder with time
  • Whenever an evil thought of copy/pasting something comes to your mind - slap yourself. It's wrong, wrong, wrong
  • Duplication kills maintainability! The only way you can fight with duplication sin is extraction and reuse.
  • The problem with it is that the more duplication you have the harder it gets to remove it. Because every clone might contain subtle changes, and this is either because somebody made it work a bit differently on purpose or somebody was fixing a bug and was not aware of these 10 other places in your codebase that are working the same way. So extract and reuse as soon as you spot the duplication. This will help you with testing. Every additional clone will require testing. So the more clones you have the more testing you will have to do. Less clones - less coding and time wasting. As already mentioned, if you have cloned a particular piece of code, and later on you identify a bug in it, it will require a lot of time to find all the instances of the cloned code and fix it. And the harder it will be if the clones got modified since they got created. So extracting code and avoiding duplication will help you change and implement new features quicker and with confidence.There are tools that can identify cloned code and save you a lot of time to do the searches manually, still you will have to go through all of them, asses the impact and see how easy it will be to remove the duplication. And some times it will not be easy at all!The last 2 commandments are not technical at all. They're more about soft skills, yet in my opinion they're as important as the other 8 I mentioned so far.
  • Communication is a very precious skill. Often underestimated.
  • A team with people that understand each other very well and can communicate effectively is a treasure. People need to know their weak and strong points and support and trust each other. This way they can speak openly, look for help when they need it and increase the confidence of both the individual and the team. Part of this is also an ability to communicate important information to the business on time. Often this can decide whether given project will be successful or not. It will also reduce stress and pressure. Let engineers do what they do the best - programming. Let project managers overlook the project and make sure everything is going in the right direction. But to do that they need to know about your problems early and understand the impact. Don't just tell them you have a problem. Talk to them about what the problem is, why you have the problem and give them potential solutions, so they can talk to the project owner who can decide what to do. It's really not easy to do all 3 jobs effectively at the same time. So if you can, avoid it at all cost. The decision point is crucial. Try not to delay making a decision until the last minute. Lack of decision is often worse then making a bad decision and ends up mostly with a project being delayed. I am not talking about making hasty decision here, without thinking the whole thing through, but do not delay that unnecessarily. And this applies to every level of the business - starting from the bottom with developers and ending up at the very top with business owners.
  • This one I feel will be a controversial one.
  • But I strongly believe some people are not fungible. This is a new word I learned recently. Fungible means not replaceable. Or in this context very, very hard to replace. The thing is, it takes time to train people, to get them up to speed so they understand your business, they way it works and operates. And it you add to that talent, you get a pretty unique combinations that can often decide about how successful your company will be. The best people will drive the team and the business to success. And it is very hard to find very good and talented people. They don't usually grow on trees you know. So keep them happy and don't let them go away easily. Happy people will be the most productive – don’t upset your best people! They will also motivate the others and increase the productivity of the whole teams, and what go with it - the whole business. You would be surprised how often it's not money that is important for them. If you give them a bit of freedom, if you let them grow, learn new things, improve - they will achieve fantastic things. Yes, there is the "hit by the bus" factor. One person, that knows that one very important things, suddenly is hit by a bus, and you loose all of that in one minute. But you need no bus to achieve a similar effect. You can loose this kind of person very easily by just not looking after him very well. Some things needs to get documented, so others can use and spread knowledge of this one person, but don't also forget that the attitude of this one person spreads within the team. It's very possible that after some times some more talent will grow within your team. But it also works the other way around. Like in your garden. A weed, can kill all the healthy plants that you've been growing so hard over time. Keep an eye on your garden, keep it healthy and you will have good harvest every year.
  • Ten Commandments Of A Software Engineer

    1. Ten Commandments Of A Software EngineerSebastian Marek
    2. • a Pole living in Sheffield • over 12 years in development • Pascal, C++, PHP, perl, python, Java • co-author of 2 PHP books • big fan of process automation • TDD and CI • occasionally contributes to open source projects • wants to be a knight@proofek
    3. @proofek
    4. Couple that works for me…
    5. I. Thou shalt not disrupt the legacy system.1st commandment
    6. Problem:• Obsolete technology• Business critical• Poorly documented• Change risk vs. costly maintenance I. Thou shalt not disrupt the legacy system.
    7. Solution:• extract• blackbox• Hide behind well defined interface I. Thou shalt not disrupt the legacy system.
    8. II. Thou shalt not re-invent the wheel.2nd commandment
    9. • Repeatable operations • In-house framework vs. open source framework • Training and support costsII. Thou shalt not re-invent the wheel.
    10. III. Thou shalt commit often and your messages shalt be informative3rd commandment
    11. • Right tool for the job• Commit frequency• Commit verbosity III. Thou shalt commit often and your messages shalt be …
    12. commit 971704e40b00cbd5fde612ed5aeb96e174bc9d2a Author: Verbose Guy <verboseguy@email.net> Date: Tue Nov 23 16:30:16 2010 +0000 Expand on comment commit 38b22c0b4ed15ddf003d6e1d7fb879349a867957 Author: Other Stuff Guy <otherstuff@email.net> Date: Mon Nov 22 16:26:27 2010 +0000 Changes to cancel other code commit 04f1f73b9ad9a2fa968cc3d16701c84f10965e66 Author: Generic Guy <generic@email.net> Date: Thu Nov 18 16:16:19 2010 +0000 Initial commit of the entire client applicationMeaningless commit messages
    13. commit 971704e40b00cbd5fde612ed5aeb96e174bc9d2a Author: Fixed Guy <fixedguy@email.net> Date: Tue Nov 23 16:30:16 2010 +0000 Fixed commit a69657b2045f1105cc940b67bab4b80b0e07ebe9 Author: Did Tests Guy <didtests@email.net> Date: Tue Mar 22 15:29:03 2011 +0000 Unit tests to prove the fix commit af1e80d98c9d8b6fe40efd3eadc27a9d4b1a2420 Author: Failed Codereview Guy <failedreview@email.net> Date: Wed Nov 24 17:07:16 2010 +0000 Code review changes, rename fileUseless commit messages
    14. commit 971704e40b00cbd5fde612ed5aeb96e174bc9d2a Author: ProperComment Guy <propercomment@email.net> Date: Tue Nov 23 16:30:16 2010 +0000 Fixed <TicketID>: Scheduled changes cancelled without cancelling engineering appointment Do not let scheduled changes to be cancelled without calling in, as there is an appointment that needs to be cancelled commit af1e80d98c9d8b6fe40efd3eadc27a9d4b1a2420 Author: ProperComment Guy <propercomment@email.net> Date: Wed Nov 24 17:07:16 2010 +0000 Fixed <TicketID>: Missing data in migration email Added the extra variables in the email needed for a customer migrating from <a product>Informative commit messages
    15. IV. Thou shalt document early and while thy mind is fresh4th commandment
    16. • Document from the beginning of the project• Developer documentation – Automated documentation – Real world examples – Hints and tips• End user documentation – Internal – external IV. Thou shalt document early and while thy mind is fresh
    17. V. Fear not the Priests of Quality Assurance nor the Altar of Testability, though they be stained with the blood of thy brethren; for they are the Salvation of the Righteous, and the Servants of our Lord, the Customer.5th commandment
    18. • Manual testing vs. automated• Unit tests• Functional tests• Frequent and early integration• Setup CI server• Fix bugs ASAP• Take ownership V. Fear not the Priests of Quality Assurance nor the Altar of …
    19. VI. Designeth not for complexity, but for simplicity; and wherever the Beast named Complex shall rear its ugly head, smiteth it with thy Sword named Modular, and let no Module be known by the Name of the Beast.6th commandment
    20. • The curse of overengineering• Convention over configuration design paradigm• Complex problems are best solved using simple solutions. VI. Designeth not for complexity, but for simplicity; and wherever…
    21. "Make everything as simple as possible, but not simpler” Albert EinsteinVI. Designeth not for complexity, but for simplicity; and wherever…
    22. VII. Thou shalt not kill (maintainability)7th commandment
    23. • Coding standard that everybody follows • Keep your code under control – Size – Complexity • Remove dead codeVII. Thou shalt not kill (maintainability)
    24. VIII. Thou shalt not repeat yourself8th commandment
    25. VIII. Thou shalt not repeat yourself (Copy)8th commandment
    26. • Copy/paste temptation • Clones mutations • Extract and reuse ASAP • Tools that support clone detectionVIII. Thou shalt not repeat yourself
    27. IX. Thou shalt speak up early and often9th commandment
    28. • Effective communication within team – Trust – Weak and strong points • Effective communication within business – Communications channels – Open and honest – Provide options • No decisions vs. bad decisionsIX. Thou shalt speak up early and often
    29. X. Thou shalt recognize and retain your top talent.10th commandment
    30. • Non fungible people • Experience + talent • Retention policy • “Hit by a bus” vs. “Upset and unhappy” • People gardening – fertilizers vs. weed controlX. Thou shalt recognize and retain your top talent.
    31. Thanks to: Pictures • http://www.flickr.com/photos/biscuitsmlp/3439419556/in/photostream/ • http://orangeroom.deviantart.com/#/d4rsmkf • http://www.flickr.com/photos/imnotquitejack/4099186535/ Further reading • The Ten Commanndments of Software Engineering - http://bit.ly/IgHZTu • The Ten Commandments of Software Quality - http://bit.ly/yJfatp • The Ten Commandments of Egoless Programming - http://bit.ly/atT1F9Big thanks
    32. Questions? https://joind.in/6290Q&A