Software Development

Tools are not skills

July 29, 2013 by Ed Woodcock. 18 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

I always find it fairly amazing how many questions appear on Programmers.SE, and Stack Overlow, with the subject of “Which x is better?”. Equally, I’ve been involved in a conversation with co-workers and friends on many occasions where the subject line starts with “What do you think of x?”. The commonality of these two separate threads is that the x is always a language, framework, or tool.

I want to go out on a limb here, and state my conclusion at the start of my essay:

Learning a new tool does not make you a better developer.

Learning a new technique makes you a better developer, tools are just there for convenience.

I’ll start with an example from my own experience. I started off as an ASP.NET WebForms developer straight out of University. I quickly became very knowledgeable about the framework itself, learning how to force it to work for any edge-case I needed, and learning how to build extensions and re-use previous components effectively. I considered myself a talented developer, and was considered to be very highly skilled by my employers. Upon reflection, it is now clear to me that I was a terrible developer.

After a while, the ASP.NET MVC framework was publicly released, to much fanfare. I scoffed, safe in the knowledge that I could make any website faster, and with more functional stability, than any other developer that I knew could develop things in the MVC framework. I began to learn MVC, and being unused to the pattern, struggled to really understand the principles behind how to develop on it. I was a brilliant ASP.NET WebForms developer; I was a terrible developer.

A little while after that, my WebForms project came to an end, and I surveyed the carnage. Bad use of JavaScript was the really key example, because I didn’t understand that putting your JS inside the page and running it as-and-when a control was used was costly and slow. Code reuse in the backend was there, but not ideal, as many actions were done specifically for the page that called them, as opposed to sharing a common data access methodology. The UI code was bloated and ugly. I took this as a good opportunity to start using the MVC framework; clearly it could result in cleaner code, I had seen other coders achieve this for myself. I became an excellent MVC developer. I was still a terrible developer.

Eventually, I came to the realisation that the MVC framework was not ideal. It had some clunky and unwieldy features (such as Microsoft AJAX), and, while it could lead to very clean code, it often did not.[1] It was around this point that I began to learn NUnit, and the principles of TDD; I quickly became a Unit Testing aficionado, and the code I produced jumped up in quality.

At around the same time as learning TDD, I began to investigate the Agile methodologies, and how they could help my development skills. This was the real turning point; I started using my own little Kanban board to manage a project backlog, and watched the quality jump again due to the increased visibility of what I would be building and the increased ability to group tasks with other important tasks. I’d used a technique that I’d never considered to be part of development, as it was neither a tool nor a language, to improve what I was developing. I had learned how something worked, not just how to use something, and it had made my code better.[2]

Since that turning point, I’ve become much more introspective, examining my skills and trying to see if I really understand how something works, not just how to use it. I’ve written my own MVC framework in node.js to prove to myself that I understood not just how to use the MVC pattern, or how to code JavaScript, but that I really understood why the pattern pushes you to better code. In the process, I became intimately familiar with the HTTP spec, and now really understand how the web works, not just how to build things that run on it.

This brings me back to my initial conclusion. It’s clear to me, in retrospect, that I have progressed as a developer not by learning how to use ASP.NET MVC, or how to use jQuery, or how to use node.js, but by delving a little deeper; learning how to apply the MVC pattern in a different language with different principles; learning how the underlying framework of WebForms really interacts with the web browser, not just how to write a custom datepicker control.

It’s very easy to get entranced by a new tool. Perhaps you’re enamoured by the features of a framework, being certain it’ll let you build your apps faster, or more robustly. Or perhaps you’re certain that Silverlight will let you build perfectly acceptable rich client applications without having to learn a new language[3]. I’ve done it myself many times. The trick is to realise that, yes, new frameworks are great, and you should broaden your horizons as much as possible. Just don’t forget that frameworks are transient, and tools become outdated.

We can really see this attitude at work in the recruitment area of the IT industry. Every job advert I’ve seen in the past year has “$language$ developer required”, or “$framework$ developer required” as its title, and contains a list of frameworks and tools that you are expected to have at least 3 years of experience in using[4]. What recruiters and HR managers cannot seem to understand is that each and every framework, tool, and language, has a number of parallels.

Let’s take C# for an example. Yes, C# is very Microsoft-centric, and the .NET framework has a specific set of tools you’re likely to use, NUnit for example. However, at its heart, C# is very similar to Java. Yes, you’re going to declare an anonymous function in a completely different way, and you’re going to use JUnit, as opposed to NUnit, but any C# developer worth his salt should become fully operational in Java in a very short period of time.

On the other hand, your average C# developer may well struggle with Ruby, for example. Dynamic languages and static languages are so different in usage that they require totally different techniques and patterns to use[5]. Dependency Injection? Don’t really need that in a dynamic language. Interfaces? Nah, not like you’re used to.

How do we fix this problem? Well, there are a number of root issues here. The first is developers truly believing that being intimately familiar with, say, rails, makes them a good developer. We fix that by encouraging newer devs to be multi-disciplinary. I firmly believe that the best way to enact change in such a broad area as development is from the bottom; if every new developer comes into the game believing that they need to be familiar with more than just the language, and framework, that’s directly in front of their face all day at work then many of them will go out of their way to learn a broader range of techniques, instead of just learning their framework of choice more intimately, or new a framework every now and again.

The second issue is the issue of organisational change. Most development houses do just one framework, and are very keen to continue to do so. On one hand this makes perfect sense, why change what already works? I recently had a conversation with a developer at another organisation about node.js: he claimed that node.js was perfect for every use case, I assured him that it was not[6]. This attitude of one-size-fits-all is problematic, as developers in small companies aren’t going to be exposed to the broader range of approaches you’ll see in large companies where they recognise that sometimes you want your backend system to be written in a different manner to your API. This is, again, something that needs to come from the bottom. If you’re pushing your own boundaries, discovering new techniques, you’ll begin to learn which are the most appropriate for which scenario. Don’t always punt for the new and shiny, try and keep a level head and really think “do I want to use this tool because it’s the best thing for the job, or because I want to use it”.

The final issue is hiring. This one can only change from the top, so I implore those of you who are in a position to influence the hiring process in your organisation to look at a developer’s skills, not just their résumé[7]. It still surprises me that most development houses either don’t have a development test, or have one that only deals with their core technologies, not the skills that lie behind their use. It would be amazing to see a community resource containing not just a list of “good questions” to ask, but of good skills to look for, and how to look for them effectively.

So, I’ve spoken about how I’ve developed as a programmer not by learning new languages, but by pushing my boundaries in other ways with new management techniques and improving my understanding of the underlying principles of the languages I do know. I hope that a few people who read this can look at their own skills and think “you know, I understand how to use this, but do I understand why?”. Real change is slow and difficult to enact, but in such a young, and social, industry we have an incredible opportunity to make changes as a community.

[1] I have seen developers write five thousand line actions inside a controller, through both laziness and lack of knowledge. Those of you with MVC knowledge should shudder at the thought.

[2] Don’t get me wrong, I’ve not yet hit the pinnacle of my development abilities, I doubt I’m anywhere near (or that I will ever really get there). Everyone has more skills to learn, myself included, and I dedicate a large amount of time to investigation of new things, and practise of the old.

[3] I once had a fairly involved argument with a colleague about whether Silverlight was worth using. I, unfortunately, lost, and the now-legacy Silverlight app has caused a myriad of deployment issues and at least one developer to leave the organisation.

[4] I particularly love ones that are “$cms$ developer required”. Those go straight into my trash.

[5] Yes, C# has the dynamic keyword. No, that doesn’t make it dynamic; dynamic in C# is just a slightly more ducky version of var.

[6] Batch processes was where I finally won that one. Anyone writing enterprise-sized batch processes in node.js has a serious case of myopia, in my opinion.

[7] I recently went to an interview where the only technical question I was asked was “What is the difference between “visibility: hidden” and “display: none” in CSS. This is not an accurate gauge of anything.

 

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

Why CS teachers should stop teaching Java applets

May 3, 2013 by Andrew Thompson. 21 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

As a veteran of applet development (see credentials below), I think it is high time to make a call that teachers should stop teaching applets in general, & especially AWT based applets. Applets are an advanced and specialized type of app. that has little place in the real world around us (most things that are done by applets can instead be better achieved using Javascript and HTML 5).

It saddens me to see new students ‘tossed in at the deep end’ to learn how to make an applet.

The reasons are multiple, but first, I’ll look a little at the history of applets and why applets were ever considered a good idea for teaching small, simple projects.

Applet vs. Frame

The simplest applet is:

import java.applet.Applet;
import java.awt.Label;

public class HelloWorldApplet extends Applet {

  @Override
  public void init() {
    add(new Label("Hello World!"));
  }
}

Looks simple, right? This hints at the primary reason that applets were taught.

It only takes a handful of code lines to see the end result.

But an applet gets a size & position on screen from the HTML that loads it. So an applet also requires a little HTML E.G.

<html>
<body>
<applet 
  code=HelloWorldApplet
  width=400
  height=200>
</applet>
</body>
</html>

This makes the total for a working applet 17 LOC. Not looking quite so simple now. Worse, many developers think ‘any old mark-up will do’ when that is very much not the case. Missing opening or closing elements make the HTML invalid and how a browser will interpret it is anyone’s guess.

Compare that to an application that behaves in as smooth a manner:

import java.awt.Label;
import java.awt.Frame;

public class HelloWorldApplication {

public static void main(String[] args) { Frame f = new Frame(); f.add(new Label("Hello World!")); f.pack(); f.setVisible(true); } }

So, while it takes just 9 lines of code for the simplest of applets (even including the @Override notation), while 12 LOC for the application doing the same thing, add the HTML and it becomes 17 lines for applet/HTML vs. just 12 LOC for the application.

AWT vs Swing

Time moves on, and the Swing component toolkit was introduced as a replacement for AWT. Nobody uses AWT anymore. Most Java GUI developers started using Swing, and those that have used AWT have largely forgotten the finer details.

This is relevant to the student in terms of getting help when they get stuck. It does not matter who we are, when approaching new areas of CS, we all tend to reach for whatever resources might help us understand the new technology. For a student the best resources are firstly the text books and class notes, but those typically only go so far at explaining, and the rest is from things like the JavaDocs, the Java Tutorial, searching the net, or asking for clarification on forums.

Those last two are particularly relevant in that:

  • There is a slew of extremely poor AWT based code available on the net.
  • There may also be some poor Swing based code out there, but usually there is a Swing programmer nearby that can point out the deficiencies in it.

Industry uses Swing and that is all that Swing programmers know and remember. AWT is obsolete, and a dead end in career or learning.

So let’s now look at the proper way to write a Swing applet & application. The Java Tutorial warns us that all Swing code should be started and updated on the Event Dispatch Thread, which (ironically) is an AWT based Thread.

A simple Swing applet might then be:

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.lang.reflect.InvocationTargetException;

public class HelloWorldApplet extends JApplet {

@Override public void init() {

@Override
Runnable r = new Runnable() {
  public void run() {
    add(new JLabel("Hello World!"));
  }
};
try {
  SwingUtilities.invokeAndWait(r);
} catch(InterruptedException ie) {
  ie.printStackTrace();
} catch (InvocationTargetException ite) {
  ite.printStackTrace();
}

} }

This is slightly verbose (25 LOC) for strict clarity, but could be reduced to:

import javax.swing.*;

public class HelloWorldApplet extends JApplet {

@Override public void init() { Runnable r = new Runnable() {

  @Override
  public void run() {
    add(new JLabel("Hello World!"));
  }
};
try {
  SwingUtilities.invokeAndWait(r);
} catch(Exception e) {
  e.printStackTrace();
}

} }

It could be further shortened (from 20 LOC) by declaring the Runnable inside the SwingUtilities method call, but I find that notation to be confusing & prefer to separate the Runnable into a clearly defined instance.

And now the Swing equivalent application, using the same ‘short guidelines’.

import javax.swing.*;

public class HelloWorldApplication {

public static void main(String[] args) { Runnable r = new Runnable() {

  @Override
  public void run() {
    JFrame f = new JFrame();
    f.add(new JLabel("Hello World!"));
    f.pack();
    f.setVisible(true);
  }
};
SwingUtilities.invokeLater(r);

} }

Just 18 LOC in total.

Not very much coding to see our simple message on screen, in a free floating Swing component.

Embedded vs. not embedded

Security

Why won’t the applet load my input file?

By default, Java applets run in a security sand-box that prohibits many actions which might be damaging to other applets, the browser or the user’s machine.

While the security sand-box is of great benefit to end-users, it makes the life of the developer difficult. And it has just become that much more difficult in Java 7 update 21.

In Java 7 Update 21 Security Improvements in Detail Markus Eisele notes:

With the introduced changes it is most likely that no end-user is able to run your application when they are either self-signed or unsigned.

While that warning is a little extreme, I agree with the underlying point being made. A user (or in this case you, the teacher) will need to OK some very scary dialogs, and possibly lower the default Java security to an unsafe level, before being able to view an applet.

Error reporting

My applet is broken but shows no errors! Where are they?

The System.err stream used for displaying stack traces appears on the command line (or in the IDE) when running an application. When a stack trace occurs in an applet it is sent to the Java Console, which is (by default) not configured to be shown.

Class caching

I changed my applet but the browser shows the same!

Many times I have responded to applet problems where the questioner swears they have changed the code & recompiled it, yet the browser is still showing the old values. The solution is relatively simple when you know how – flush the class cache from the Java Console. To someone learning, it is typically a complete mystery.

Embedded conclusion

Those 3 problems alone have probably earned me a quarter of the reputation points I’ve so far gained for applets on Stack Overflow. They pose huge problems when developing and debugging applets.

Conclusion

The question really comes down to:

Are you teaching Java/CS or how to deploy applets?

If the former, use JFrame based applications and side-step all the problems that are inherent to an embedded app. And don’t even consider teaching AWT components – they are obsolete & Swing takes only a few more LOC to get something on-screen.

Author Credentials

So who am I?

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

What programming concepts I should master to have a deep understanding of my craft?

March 4, 2013 by LachlanB. 14 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

So you’ve been working as a programmer for a couple of years, and you want to become a good programmer. But not just a good programmer, you want to be a GREAT programmer. You want to paint with ALL the colors. Hell, you want to paint with all the dimensions. You want to be the GURU of programming – not just some nerd that’s stuck in corner that knows every namespace in the .NET API and can punch out a website in a day – you want to be a Michelangelo. A Picasso. Programming isn’t a science, it’s an art. You want to be respected.

Boy that’s a big ask.

So how do you get started?

By now you’ve hopefully realized that what makes good programmers great isn’t necessarily their technical skills. Your technical skills can be AWESOME, but if you don’t know what your customer wants, they amount to diddly squat. Of course if you know what your customer wants but don’t have the technical skills to back it up, you’re also up the creek. So what are the technical things you want to learn?

* How to write “DRY” code. DRY stands for “Don’t Repeat Yourself”. Copy and paste coders are not real coders. If you find yourself writing the same (or similar enough) lines of code more than once, it needs to be cleaned up so that you don’t have duplicate code all over the place. This will actually keep your codebase smaller, easier to maintain and reduce your bug count. People call this refactoring and it’s a daily part of our job. It’s not an optional extra for the end of a project.

* How to keep it simple. Once you’ve got the hang of refactoring and cleaning up your code as you go, you’re going to have to learn the next principle of keeping it simple. Too often once programmers have got it into their head that they need to not repeat themselves, EVER, and so many code bases grow to be an abstracted monstrosity. I’ve seen huge heaving code bases that take minutes to compile, but the application itself hardly does anything. Keeping things simple above all else is your goal.

* Learn the principle of YAGNI. You Ain’t Gonna Need It. All too often as programmers we want to make sure that we cover all our bases. The customer has asked that the application is to do X. If that’s the case, then they’ll probably want it to do Y and Z too. We might as well spend another 3 days putting that in, after all they’re going to ask for it anyway. Once again, you end up with a much bigger codebase and app than you need, and half of the code in there isn’t being used. Keep it simple!

This can be a very difficult concept to master. Making your solution flexible, customisable and forseeing future requirements is a very important part of our job. This is where I think that programming can be shown to be an art – there’s no hard and fast rule here. Ultimately it’s up to the programmer(s) discretion over how flexible a solution is – it involves constant judgement calls and a weighing up of the pros and cons. Normally the questions that you want to ask yourself are:

“How much extra work will it be to make this more flexible?” vs

“How much time do we have?” vs

“Will they really need it?” vs

“is this making the code worse or better?”

These kind of questions are very difficult to answer on your own. Two heads are so much better than one! Often just talking through the problem and the solution with another guy can help you work out the right approach yourself. Even picking up the phone to call another programmer to see what they think can save you a lot of pain.

* How to constructively review other people’s code. Code reviews can send a shiver down the spine of the most experienced programmer. They can be harrowing, aggravating and an ultimate waste of time. They can also be a delight, an opportunity to learn from others and to improve your skills! The most important aspect of code reviews is not what technical details you are looking out for, but the attitude and expectations that people approach the review with. If you’re dying to bag out someone’s code and make them feel bad, if you’re on the witch-hunt to see how many bugs you can find, then you’re going to be in trouble. People will resent these code reviews, nobody will want to help anybody else and most importantly, your code will not get any better!

The approach that you want is for everybody to go in with the mentality that “we’re here to learn from everybody else and to improve the code”.

* Design patterns. Reading the classic book on design patterns can give you a lightbulk moment – “oh, THAT’S how I solve that messy coding problem”. The danger that most people have is overapplying design patterns and you end up with a bigger mess than you started. Once you’ve learnt how to use a hammer everything starts looking like a nail. So don’t overzealously use them for the sake of it.

* Keep up to date with frameworks & libraries. You don’t have to use them, but you need to know what they do and their pro’s & con’s. A great example of this is SignalR - before this came along I would have been adamant that there is just no way that you can easily do realtime notifications within your web application. Turns out that before signalr there were libraries like pubnub who do this kind of thing with ease – but I had no idea! If I hadn’t kept up to date I could have been the one spouting rubbish (well, more often than usual, anyway). Keeping up to date with libraries and frameworks will also show you how if something seems way too hard to do then there’s probably (hopefully) a much easier way of doing things. Don’t write your own service bus layer when there’s MSMQ.

* How to comment your code. If you’re not commenting code then you’re making your life more difficult. When you come back to that function you wrote 6 months ago you’re not going to have a clue why you wrote it in such a convoluted way. Hey, it turns out that you did it that way for a reason! And BTW you shouldn’t simplify this mess because you’ll actually break it!

You also want to learn how to write down that complicated algorithm in a flowchart or just write it out in english. Don’t expect that someone will spend 2 days trying to reverse engineer your code. Don’t expect that people in the business will learn/remember/understand that complicated logic that they asked you to do. You’re going to end up pulling out this flowchart in at least 3 meetings in the future whenever people say “So what happens when x happens and then y?”

* How to write unit tests. Writing tests is a great way to ensure that your code will continue to work, even when some dufus comes along and modifies the database schema without telling you. Okay, well your code definitely won’t work, but now you can catch it the very day that someone renames a column. Instead of catching it three weeks later and finding out that your application hasn’t been calculating numbers properly. You’ll also want to learn what TDD is and see if it’s a good fit for you.

* What dependency injection / IOC is. A contentious argument for sure, but one you want to be well informed of. It’ll also give you a massive leg-up on when you see your first project that uses DI. If you don’t know what’s going on, you’d swear the code is backwards and insideout.

* How continuous integration is your saviour. I can’t imagine working on a project these days without CI. If I didn’t have a build running everytime someone checked in some code I would be quite terrified. It’s your safety net, your progress indicator and your one-click deploy solution all in one.

* Know what’s going on under the hood. For example, calling a web service – what’s it actually doing? If it’s WCF it’s creating a SOAP service call – you should check out the actual data that is sent over the wire sometime. It’s massive. If I hadn’t peeked under the hood I would have had no idea just how much bandwidth it needs. When it comes to programming, nothing just happens magically.

* Learn the gist of quite a few programming languages. You’d be surprised what you can learn from other areas. If you don’t know how simple python is nor how easy a web application is in ruby on rails, then you’re only seeing one side of the coin. If you’re coming in from strictly typed languages then javascript is a bizarre world in itself! I’m a c# developer and I’ve found that java guys think very differently. So do PHP people.

* Peter Rowell has a great post on how to debug. I agree with everything he says – real programmers don’t guess, they debug. If you think or hope something is working, you’re probably wrong. You need to SEE it working and prove that it’s working. I can’t tell you the number of times I’ve looked at code and said “there, that will work” only to run it and see that it doesn’t. Actually while you’re at it, read his other answers. There’s a voice of experience.

* Make fun of the losers. You also need to learn which programming languages you can successfully make fun of without someone actually punching you in the face.

So what about the non technical stuff? These are the hard ones.

* How to justify your project to management. Management will continually conveniently forget what the point of your project is. You need to be able to explain it in 30 seconds, and then if given the opportunity explain it in 360 seconds. How it benefits the business and why. If you can’t articulate it, nobody else will be able to, and pretty soon people will be asking “why is that guy here?”

* How to explain to management what you’re doing and why. This is different to justifying your project. Some bosses like to know what you’re doing every day – when s/he does, you better have a good answer. “Working on code” is not a good answer. “Adding feature X that will solve problem Y” is a much better answer.

* How to clarify and write down what the customers wants (“requirements”). This is an art in and of itself. If you can do this, your programming job will be A BREEZE. You know all those arguments and problems that you had with people outside of IT? They can be resolved by writing down what people say. Write it down in front of them, during the meeting. Learn from technical BA’s – they are a Godsend.

* How to estimate. People will ask you for an estimate, be prepared. If you don’t know what you’re doing, multiply your estimate by three.  This is not to pad it out – this is to make it more accurate.

* How to plan your project. Remember, only 30% of your time on a project should be coding. That’s thirty percent.

* How to differentiate between a bug, an issue and a feature request. They are all different.

* How to direct other programmers without getting up their nose. You also want to know how to motivate them.

* How to get along with other programmers. We’re a strange breed. Getting along with us can be a challenge – you’re going to have to learn some ninja skills. I can recommend “how to make friends and influence people” by Dale Carnegie. A classic.

* How to work with maniacs, psychopaths and just plain crazy people. There’s a lot of them out there. You’re probably one of them yourself.

 

Phew.

 

So what’s the most important thing to learn?

How to GET STUFF DONE. All the theory in the world won’t help you if you can’t get stuff done. Everything above is a waste of time if you’re not getting stuff done. Can this be taught? There’s an interesting question.

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

How to successfully work in a distributed team

September 23, 2012 by Hoàng Long. 6 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

Working in a distributed team is becoming more and more popular. With the power of Internet, today we can easily work together without worrying about physically travelling to work. It saves time, fuel, and personal energy. Can anyone imagine anything better?

But, all the convenience comes with a price. Co-located workers have the advantage of direct communication, which is often underestimated. When you have all of your coworkers in a room, they will answer you immediately when you ask, “Is that document is ready?” or “Can our original design support these new requirement changes?”. When the team are distributed in many locations (and possibly many time zones), things are quite different. We must wait for our emails being answered, or the chat reply message, while the others are on their other tasks. We may get stuck and need help from another team member who are sleeping while we are at work. That’s not only irritating, but also become a real challenge for any distributed team want to push their productivity toward their maximum potential.

I have been in this position more than once. Some were school projects, some were start-ups with my friends, and some in my work elsewhere. Some of them failed desperately, the rest succeeded. What I learned from them is: the way we do things as a programmers have a big impact. And success is not only for the Project Manager – it’s something we programmers can be proud of – when we contributed in it.

Teamwork

 

There are three key principles to success: Communication, Trust, and Enthusiasm

 

Communicating

Communication

Communication, communication, communication. I can’t stress this enough. Making sure everyone is on the same page is critically important, especially when you’re building a product a continuously changing product. In a fast-paced environment, a developer may take harmful shortcuts or forget important details if the rest of the team is not aware of their actions. Many times, I had to remind a team  member about a requirement he forgot, or explain the reason for our design the third time to the same person. It’s annoying, but it’s far better than letting developers make assumptions and cause irrepairable damage to the project.

Given that the team is potentially distributed all over the world, communication is harder but not impossible. All the team should sit together (via Skype or similar) to agree on a “communication plan”. In our case, we had two teams: client and server which works on different places with different time zones. we decided that everyday the server team would build a new version at 12:30 pm, then the client team would check to see if there’s any problems. Then, at 4pm when everyone in the server team went home, the client team will begin their work and give feedback to server team by the next day. The check at noon guarantee s that the build is not broken so badly that the client team can’t fix it.

One of the other ways to enhance communication is building a “responsive” culture. “Respond early – respond often” – that’s our motto. When you get an email and don’t have the chance to read it thoroughly, just mark them as “to read” and send a message that you’re doing on another task and will look at their problem as soon as you’ve time. That will help the people on the other end switch to another task in the meantime. (*)

 

Teamwork Trust 

Believe me, trust is very important. If people think you are not doing your best, they won’t either. Trust others and they will trust you. Do your work so that your team can trust you, and they will be much more inclined do their work. Be as transparent as possible. Make it clear what you’re working on. All of those things are easy to say, but it requires attention and care to get them done.

Once, I joined in a start-up where everyone was eager about what we were going to build. But we were located in different countries, and also had day jobs. Several weeks passed and we got our infrastructure setup ready. But then we got stuck in a vicious cycle: late response time, endless discussion about what the project will do, and soon everyone was tired of meeting without seeing anything done. The project got cancelled.

The lesson to be learned here is: we wanted to build something, but we failed to show each other that we wanted to put forth our best effort. As a result, any trust could have been cultivated was destroyed.

 

Happy team Enthusiasm!

Share your vision. If you don’t love what you’re doing, you are killing the morale of others. We all love working in a enthusiastic environment, so just make it :-).

Being passionate about the project’s goal is a sure path to victory: I have noticed that when myself and other team members have a positive attitude, all team work better with less conflict and miscommunication. We even feel much better.

Enthusiasm is infectious. Coming up with new ideas (sometimes stupid) is a way to show passion. That means you don’t only do your work, but you do it with heart. If you think of any cool idea, tell others right away. Don’t be lazy and say: “I will catch up with him tomorrow” because that tomorrow will never come. Tomorrow, other tasks will pull you away along with your best ideas. If you think the idea is not mature enough to present, put it off somewhere you will absolutely look at when you have free time. I feel that a sticker right beside the monitor is not a bad idea.

Last but not least, keep a close eye on what’s going on. Revise early, revise often. No matter what you’re doing, which role you’re playing, you should be responsible about project’s success. Tell the people in charge about any risk early.

In closing, a programmer is not simply a technical worker. That’s not the spirit – any laborer can learn their work for once and apply it the same way for many years, but that’s not us. We live and breath in the ever-changing technology environment, and we come here because we love it. Working in a distributed team is not only a difficulty, but also a challenge that many of us seek to overcome.

(*) Manage your time wisely. Time management: Answer too many requests and you will not get anything done. Don’t answer then they will wonder why you don’t respond. They can’t see you are busy. Balancing the workload is an art. But for starters: Speak the truth and try to be as simple and as clear as possible.

(**) The images used in this post are credited for Stock Exchange

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

Code stinks! What do I do?

June 11, 2012 by ubermensch. 4 comments

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati

Introduction

A quick search for the words “bad code” and “code smell” on Programmers Stack Exchange fetches a lot of results. So this means that several people are having this problem. This article present a few ways to work with this problem from a non-technical 30000 feet perspective.

A few caveats

  • Nobody can write perfect software; you can improve it forever. There is always room for improvement.
  • Programs keep changing based on requirements and requirements based on market environment. Hence code is dynamic and prone to error.
  • Bad code is not directly proportional to programmer inefficiency. There are a lot of other factors that contribute to bad code.
  • This article is written from the perspective of enterprises engaged in the business of software.
  • In my opinion, there are a few hopeless cases where you just cannot tame it. A list of them is given at the end of the article.

What is bad code?

Though difficult to define, for the purpose of this article, we can define bad code as some piece of code that is: incomprehensible by reasonable standards,1 lacks in conceptual integrity, doesn’t have a definite structure and is a sign of more bigger problems. Technically, code smell.2

If a bad piece of code is not found, it can quickly turn into a code smell and transform into a black hole that could suck every good part of the program in.

The following are a few explicit instances of bad code

  • the person who wrote or maintains the code cannot explain it in a logical manner
  • changing one part of a program breaks another
  • improper documentation
  • lack of conceptual integrity
  • lack of standard conventions
  • lots of duplicated code
  • too many components to integrate and too many layers

Causes for bad code

The causes for bad code are many and the reasons are also multidimensional. So, causes may be viewed from three main perspectives:

Programmer-centric

  • Improper communication3
  • Lack of domain knowledge4
  • Lack of experience and understanding
  • Lack of experience in a particular tool-set or methodology

Design/Architecture-centric

  • Anti-patterns
  • Over-engineered code
  • Interface kludge
  • Lot of individual components to integrate
  • Improper layer/tier separation
  • Improper selection of technologies
  • Anemic models

Organization-centric

  • Outdated methodologies
  • Outdated tool-sets
  • Usage of legacy systems
  • Too much vendor lock-in
  • Wrong hiring policies

There are several other ways that bad code can be made, and each topic in this list deserves a separate article on its own. The following Wikipedia page provides some excellent links.

Ensuring the code is indeed bad

Before embarking on this journey, make sure that the code is indeed bad and it needs to be taken up. The following guidelines would help.

  • Do plenty of research and get to the root cause.
  • Analyze the code from multiple perspectives. Review it with another person.
  • See old versions of the code to know its evolution.
  • Always use objective standards.
  • Discard petty issues, obvious errors that could be easily corrected.
  • If possible, correlate between the code and the bugs created by the code.
  • Use standard code coverage tools to analyze the program.

Your Rank in the organization

A program is just not an entire technical pursuit. There are different priorities for the same program at different ranks and the same technique wouldn’t be a good fit for all.5 Thus your rank in the organization gives you the ability to leverage your resources purposefully. The higher the rank, the higher the resources and the bigger your influence albeit with higher responsibility. Enterprise hierarchy is one big tree you can’t always traverse successfully.

For the sake of simplicity, we assume three ranks in the hierarchy bottom-up.

  • Rank 1 – people who actually write code – programmers, developers, software engineers – scope limited to a module or a set of modules.
  • Rank 2 – people responsible for a project – Project leaders, senior developers, team leaders, software architects – scope covers the entire project in hand.
  • Rank 3 – people responsible for the delivery of the software to the customer and revenue to the organization – Project managers, Product managers, delivery managers – scope extends to the successful delivery of the project.

There is a correlation, though not directly proportional, between rank and the nature of problem. Most programmer-centric problems can be attributed to Rank 1, design-centric to Rank 2 and organization-centric to Rank 3.

A few suggestions to approach the problem:

  • Know your position and rank in the organization and approach problems that could be realistically solved by you. You may easily talk to a co-worker about refactoring but you can’t expect to implement it across teams if there are tight deadlines. Be pragmatic as what you could solve.
  • Talk to the right person. Know the scope and rank of the person you are talking to. You can’t discuss design or methodology change with a Rank1 programmer nor you could be talking variable naming conventions with your boss.
  • Take time off. A prior appointment would be good. Never ever discuss in a urgent, haste manner. Proceed on a case-by-case basis. Remember you are pitting for a future change and people doesn’t like change.
  • Always give time for reasoning and listen to the person you are talking to and never run into an argument on his style of programming.6
  • Despite your best efforts, if your underlying assumption about the code turns to be wrong, graciously accept it.

The following additional guidelines would help for different ranks

Rank 1 Communication

A person in this rank may not be fully aware of the entire software life-cycle. So you are limited about what things you could talk to but this is the rank where most of your suggestions would be accepted. Communication is the X-Factor at this rank.

  • Know the qualification, domain experience, expertise and the programming paradigm of the person. Paradigms (Object Oriented,Functional) and domain experience play a huge role in programming style and understanding. Ascertain the right area of concern.
  • Ask him to explain the code to you and share your thoughts about it. Show how your proposed method could be better. Use an objective method to stress the advantages arising out of the new method versus its disadvantages.
  • Put focus on ease of use, easy maintenance, long-term development of quality software and stress the importance of cascading effects
  • Don’t talk things beyond his reach. He is just hired to do programming not to run the organization.

Rank 2 Communication

Persons in this rank do have a lot of technical knowledge so you got to be spot on with your reasoning and facts. Also, keep all your discussions at the conceptual level. Changes at this level may take time to get implemented. Clarity is the X-Factor at this rank.

  • Ask the reasons for choosing the specific design or architecture; the constraints, advantages and trade-offs involved.
  • If the design is flawed, pinpoint it accurately. If it is a known anti-pattern, name it precisely. If there is a flaw in the business logic, describe it with the industry standards.
  • If the design, though technically sound, is too esoteric, try explaining how making it a bit simple would make it more easy.
  • Building a good design takes considerable time and energy. So try concentrating on improving the existing design to rectify the flaws rather than proposing a radically new design.

Rank 3 Communication

You are operating at a much higher level where revenue is the main priority. You must prove decisively that the present polices inadvertently lead to programmer inefficiency and thereby increasing cost. So, a lot of work needs to be put in. Remember, you are pitching for a future organizational change. Many a time, you may just not get over the line in this rank, since a lot of other factors are involved in decision-making but if you believe you could make a change, you must give a honest try. There is basically no X-Factor here though some knowledge of political science would definitely help.

  • Talk to your peers as how they feel and think about the present scenario and garner valuable support.
  • Do organizational research. Read the policies and procedures of the organization and compare them with the competitors.
  • Fix a prior appointment and have a formal agenda.
  • Never ever use subjective standards.
  • Support your views with research papers and authenticated articles.
  • Effectively use metaphors.
  • Prepare a neat presentation. Use some business buzzwords in it. Do not make it too technical. Nitty-gritty technical points can be taken up at a separate discussion.
  • Always present your views with a cost-revenue analysis and show a comparative study with your competitor.

To illustrate, if you are sure that the waterfall methodology of your company is creating delay in software delivery and thereby introducing more bugs due to cramped schedules, try doing the following.

  • Select a couple of completed projects.
  • Collect the following information regarding the projects.
  • Estimated schedules, proposed delivery, actual delivery, estimated budget and final cost
  • Number of man-hours spent
  • Number of changes proposed by the client and the hours required to complete them
  • Bug reports and the time taken to complete them.
  • Installation, maintenance and service costs.
  • Prepare an alternative schedule in an another methodology (say agile). Be conservative in your approach.
  • Now, estimate the hours that would have been saved by the new methodology.
  • Include the additional costs that would be incurred
  • Calculate the opportunity cost
  • Now put these things together and create a nice presentation. Quantify everything and convert it into costs or revenue such as “the new method would lead to a 10% decrease in man-hours that would cut project costs by 7%”
  • Initiate for a pilot project so that you could try the new methodology. You are running a big risk here but its worth taking.

Final remarks

A few hopeless (difficult to change) situations in my opinion:

  • Cramped schedules.
  • Programming thought as a linear function by the management and work allotted on the basis of pure division of labor.
  • No upfront design. Starting to code straight away.
  • Horses for courses policy. Hiring somebody to do the job.
  • Egocentric persons with lethargic attitude.
  • Right persons in the wrong jobs and wrong persons in the right job. DBA’s pushed into web interface programming and business analysts doing hands-on programming.
  • No clarity in rules of procedures.
  • Too much implicit communication.
  • Thinking too much.

There are chances that despite your best efforts, your suggestions may not be accepted. Always try to the best of your efforts and if it fails, just adopt an another method. Remember the Pareto principle; You might spend 20% discovering bad code and 80% try correcting it. Also, communicating bad code is 20% technology and 80% psychology.

Our problems are man-made, therefore they may be solved by man. And man can be as big as he wants. No problem of human destiny is beyond human beings.

  • John F. Kennedy, speech at The American University, Washington, D.C., June 10, 1963

Recommended Reading

Footnotes


  1. Reasonable standards mean the program must be understood by a programmer with the same expertise as the person who wrote it in the first place 

  2. Code smell is any symptom in the source code of a program that possibly indicates a deeper problem 

  3. Communication here means the ability to correctly understand the business requirements of the client and to explain it to fellow programmers. 

  4. Domain here refers to specialization. Domain may be computer-related such as systems programming, web programming, GUI application or business-related such as finance, human resource, production. 

  5. If you honestly believe you are hired by enterprises exclusively for your technical abilities, I suggest reading this article

  6. The only way to get the best of an argument is to avoid it from “How to win friends and influence People” by “Dale Carnegie” 

Post to Twitter Post to Facebook Post to Reddit Post to LinkedIn Post to StumbleUpon Post to Digg Post to Delicious Post to Technorati