Thursday, March 21, 2013

Working on a legacy project


Chisara Nwabara

In many ways, working on a legacy project is much more challenging than working on something fresh. You are dealing with an old dog; a creature that is less malleable and, in my experience, often times less willing to take on new tricks when push comes to shove. It takes a lot of patience and also an understanding that even though this dog is stuck in its ways, it has years of experience that should not be overlooked. So, in my opinion, the challenge is determining how best to leverage said experience so that it can be applied to the practices you’d like to bring to the workbench. Once you are able to balance the your knowledge/experience with that of the client's, the project goes much better. Linda Goldstein

I am currently on a Java project that started before Java had non-generic lists. Last month, we had to code around a bug in Java that was fixed in 2011. There are code comments from 2002. At least three different editors, with three different code generation and indentation styles, have generated code in this app. There are both DOS and UNIX line endings. Using Vector was considered good practice at some time during the lifecycles of this app. As far as I can tell, at no point has dependency management been used; all the jars are checked in.

Legacy is a challenge. You can never fix everything all at once. And what I consider a 'fix' may break something that was written several years before I learned how to code. In order to actually understand what you're doing, you have to learn not only what is a bad idea today, but why it was a good idea five years ago.

"Learn from the mistakes of history, or you will repeat them" is the common wisdom- but, like the prime directive of retrospectives says, "Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand." Those mistakes of history? A lot of them weren't mistakes. They were conclusions given a different data set than we are currently operating with.

Working within legacy constraints is a complicated puzzle. On this project, I get to make something more elegant every day. There are a lot of low-hanging fruit. It's not boring yet.

When it comes to how working on a legacy project affects my interactions with people... there is fear in this codebase, and you can smell it in the null checks and in the comments. There are too many unknowns left over from 2004; there is too much "just in case" code. I write it too; the fear is justified. The test coverage is low, and you can never be quite sure what the code upstream will do, since the Single Responsibility Principle was not (and is not) always universally approved of.

A legacy project is a complicated ecosystem in every way; it is very far from the relative simplicity of "rails new testproject" and I do sometimes wish that the only code we had to contend with on this project was written by people using the same approximate temporal set of best practice references as we.


Sarah Hutchins


I have never honestly worked on a legacy codebase. Even now, my current engagement is around teaching the client a better way to write code and the codebase is little more than an example minefield. However, I have been on the other team - the ones from whom you inherit the code, the ones who have to somehow impart all the knowledge built up, the ones who made those decisions which come back to haunt the project.

It is very easy to start out with good intentions and watch things slowly unravel. Between business indecisiveness, lack of experience, and the odd technology choice for which there is no choice, compromises end up finding their way into the codebase. The more functionality which gets added, the more cluttered the domain model became. Pressures make it difficult to do a domain model level refactoring and before you know it, our greenfield project became just another cluttered codebase.

Ramping people up in this situation is never pleasant, and unfortunately, the second wave onboarding tends to be roughest. No matter how much you try to cover when explaining things, there seems to always be that one class which gets missed or that one testing standard. Furthermore, as one of the original members, so much of the knowledge has become second nature it becomes difficult to ramp up someone from nothing. It is one thing to claim you need to tell them everything and quite another to actually do it. After all, how would you explain walking? It is a skill we learn through trial and error over a period of time and we constantly refine it as we use it. We get to the point where we can no longer consciously remember everything involved in it because the knowledge is ingrained. After being on a project for a couple months, it can feel like that. As a result, a lot of pressure ends up on the one getting ramped up since they have to ask questions about the knowledge you do not even think about anymore. Naturally this can lead to frustration over the seemingly convoluted codebase. Then, as the original team, you watch the new people come in and decry many of the decisions made without knowing why the decisions were made. Things start to get added to the codebase without the context of the old guard and it becomes even more disjointed.

This is not to say new people being added is a bad thing. It is a very good thing as new thoughts and ideas are added. The new people are also not weighed down as much by the knowledge of the past and will have a much easier time questioning decisions. Cycling in new people is one of the better ways to keep a project innovative and without the new blood, it is very easy for a project to stagnate. Furthermore, once you get through the second wave of onboarding, ramping up those who follow can be quite a bit easier. At this point you have both the originals who have the context and the second wavers who had to struggle through and can remember their difficult spots. Later ramp-ups can take advantage of both to not have to figure out all the right questions since the previous group has already been there.


Abby Bangser

While I do not think all “legacy” systems are the same, often people associate legacy code with a buggy, hard to understand code base with limited test coverage. If we look only at a situation which falls into these categories it can be a very difficult situation for a new Quality Analyst to roll on to. How do you test something that even the most project experienced testers and developers do not fully understand? Questions abound, including...How can we be sure this change doesn’t cause a bug somewhere not immediately obvious? Was this an existing bug or a new one? Where else does this change show up?

However, what I have found is the biggest struggle is not in the risks, but in redefining the concept of a “quality product” in the eyes of the customers and development team. Obviously the current team takes great pride (and should) in their product and the customers rely heavily on the application. However, everyone from developers to users have learned (and I quote) “work-arounds to work around their work-arounds”. This deep understanding of already unsteady processes leads to a desire for consistency even when it perpetuates the acceptance of bugs and hardships for the users.

There are ways to introduce change by deciding today that anything new will be written under the new standards, and to refactor existing code in a slow by steady manner. The fragmented and duplicative nature of legacy code can make it difficult to change existing functionality that spans lots of the application (ie: a standard for how to submit a form which may not be user friendly but is “copy and pasted” around to many screens). By building any new versions with modular pieces you can kickstart the refactoring process and before long have all instances called from the same method which allows for a one step change. This consolidation of changes is more likely to be approved by the customers since consistency will be maintained.

Friday, March 8, 2013

Childhood activity that most translates to current successes


Rose Fan

I can’t pinpoint any one particular childhood activity that I think translates to current successes. There are many that probably seem like candidates - Mock Trial, playing an instrument, blogging, attending a Magnet high school focused on math and science. And yet, to draw a nice little connection between those and the environment I’m in today, no matter how seemingly correlated, still doesn’t seem honest or genuine.

I thought that school and the boundaries of childhood were quite mundane. If you knew how to play the system, you could win. But it was a rat race of scores and grades and rankings that were standardized ways of measuring people and comparing them against each other and I didn’t like that. In the last few years, when I’ve been outside of those confines and have found a company that doesn’t emphasize traditional roles or structure as a means to an end, I’ve felt a lot more empowered to make decisions and figure things out.

I attribute my current successes to relatively current (i.e. no longer childhood) and drastic changes or pivot points of my life, when I finally felt like the reigns of my life were in my hands. Childhood for me doesn’t map to them, at least not in an obvious way.


Abby Bangser

I am a true believer that who you are at a young age translates to who you will become as you grow up. While I have grown tremendously from my education, work experience and travel adventures I think I am still at heart the same kid that was full of passion and drive. Growing up my parents were great about helping me do anything I wanted to try, which revolved heavily around sports (even ice hockey, though much to my mothers dismay!). Through sports I learned how to be gracious in defeat yet tenacious during competition. I learned about the impact of a weakest link in a team, from both the strong and weak positions. I learned when to lead and when to follow. And most importantly I learned how hard I could push myself and the amazing results when I did so.

Those lessons are pretty standard if you talk to any former athletes, and there are a million articles and studies that translate these into future leadership and business success. But to translate this into being in software development or a consultant took a little thinking. One thing that I remember doing even from a young age is learning from everyone. This meant even if I didn't agree with someone or I couldn't master the skill that moment I filed it away in my rolodex (this analogy in itself is thanks to one of my coaches) and kept it on file to re-attempt at a future time. I think that this understanding that everyone has something to share and teach translates brilliantly to having success as a consultant. Coming into a client's office with the humility to understand you may not have all the answers allows you to make an even greater impact while also leaving better off yourself.

Linda Goldstein

The problem with my childhood as it relates to my professional life is the perception of some people that it was too recent. I have, several times from different sources, gotten "Aw, you're my daughter's age."

I am not like your daughter and I do not have any familial obligations relevant to this situation. I am the person trying to help you learn how to refactor code, write unit tests, and generally meet deadlines. Please try to put on your professional hat and remember this.

In my opinion the love of learning is easier to have when one has not learned to not love learning- which implies that age is a form of handicap in the field of development. I have met devs with thoroughly white hair who are fast enough on the uptake to leave me in the binary dust, and I am honored and delighted to work with them and try to imitate their learning.

The activity in my childhood that I think contributed most to my current state was reading excessive amounts of science fiction.