четверг, 20 марта 2014 г.
In the 4th episode of Code Speak Loop podcast I have tried to express the idea that delivering some finished products is as important for young professional’s growth as a good job with experienced team or learning new technologies and tools are – especially in the field of software development. Since I had certain difficulties explaining what I mean, I decided to write down my thoughts so that they become clearer for both my followers and me.
What actually made me think about this are my recent attempts to bring some stuff to the public. The first quarter, which is drawing to a close now, was full of these new activities. Maybe most important is that I have recently published a Windows Phone 8 application and this week it has seen the first update. At the same time, I strive hard to deliver the second app in the nearest future – hopefully, it will hit the marketplace right in the beginning of April. Apart from this, I still have this blog, which means that I keep publishing my thoughts on a regular basis and, while this might not seem to be directly related to the software engineer’s profession, the experience of delivery is quite similar. In addition to blog, which has been around for a couple years already, together with my friend we have launched a podcast and keep doing this weird, but extremely funny thing as well. Finally, I am a full-time developer, so I do participate in the process of creating a product on my job. Work involved in all these things, loads of new experience obtained from it and the fact that delivering something turned out to be much easier than I expected made me think on what is most important about delivery, and why should I bring more of my stuff to the public.
To begin with, creating shippable products is very different from just working on pet-projects in that the obligation to deliver goods puts developer under certain constraints. These in turn make one face and do things, which would not be necessary in case the only goal of a project is just learning something new, becoming better programmer and having fun. Moreover, when we speak of delivering the results of pet-projects these constraints are imposed by the developer himself, which is by itself an essential experience. So what are the constraints? The first thing that comes to my mind is time – when trying to create something for customers it is important to set up various deadlines. One will definitely pick the timeframe for creating the first version of the product, but in addition to it, developer can have deadlines for the first prototype, for the individual features and so on. While setting up the deadlines is possible and worthy even without the goal of creating and publishing a product, having a clearly defined timeframe for each task is absolutely required when delivery is the key objective. One cannot just say that they will publish an app or finish a website for a customer sometime in the future: for most people, including myself, this is not going to work, particularly because the absence of deadlines prevents us from properly prioritizing our goals.
On the other side, through establishing time limits for our work we also bring to life constraints of another kind. The scarcity of resources, including time, simply makes developer limit the scope of their activity. Here I mean that when working on the deliverable software we sometimes have to reject our greatest ideas to be able to deliver something on time. This can manifest itself in different forms: for example, one might chose to delay the delivery of a feature significantly, despite the fact that it seems quite easy to implement and may be helpful to users. In other cases, one may decide to totally leave out something nice just because it doesn’t seem to fit in the concept of the product, whether it’s a mobile application, a web-site or a library. My job in a couple of software companies made me familiar with triaging, feature rejection and similar things, but because in contrast with, for example, Acumatica my own projects are really small I was not going to see anything like this while developing them. Despite that, I have finally found myself doing a lot of triaging. The need to limit the scope of the product does not seem to be related to its scale, because no matter how simple, say, an application is, we would come up with lots of ways to make the thing nicer, easier to use, more engaging and feature rich while working on it. Furthermore, because our imagination is by no means related to the amount of resources we have, we would continue spawning great ideas throughout the course of any project and the closer the final deadline – the more feature proposals would be on the table. In case of exploratory projects not intended for publishing this works pretty well: one is free to put in everything that looks good and be happy with the resulting mess, but when you have to deliver something it is important to both finish the product on time and keep it maintainable and consistent. Although this can make one postpone even the most awesome features, it is crucial to separate what will make it into the release from the things that should wait for their glory hour. Moreover, because such activities are very common in the field of professional software development (as well as in a business of almost any kind), it is good to have the degree of discipline required to reject or postpone implementation of the greatest ideas. I suppose there is hardly a better way to develop it than to create a product and push it to a market of some sort.
There is another thing that is inherent to anything deliverable and at the same time is irrelevant to just hacking code and experimenting with new technologies – the requirement for the product to be consistent and finished. On one side, this is strongly related to the scope of the project, because not defining it properly leads to something like feature explosion when the entire application becomes a mix of things, some of which are not finished and hardly reinforce the effect of each other, serving to confuse user instead. In case of exploration-, learning- and fun-oriented projects such state of affairs can’t hamper anything – it is impossible to confuse non-existent users. Moreover, it is good not to limit oneself to some little portion of functionality and simply implement everything you stumble upon: this way one has more room to make mistakes and to learn from them. On the other side, if one is up to delivering a product allowing it to slip into such state is not an option at all: you can’t afford the risk of either not delivering anything at all or publishing an unusable mess of cool stuff. Besides, the key difference between pet-projects and deliverables is that the former don’t need to be finished in any sense: you can just hack code, train machine learning algorithms, feed data to them and never care about the way they should be used. The key characteristic of a finished product, on the other side, is its public interface. For me the concern is usually graphical user interface, because that’s something at what I am very bad. At least two of my projects could have become something deliverable should I put more effort into designing the UI and making it convenient. The primary reason why I didn’t do this was the lack of determination to actually ship the results of my work – otherwise I would have no choice except for making the applications usable and appealing. This said, starting a project with a goal of publishing it makes us thoroughly think over the public interface right from the beginning. In my case this also has a positive consequence: since I am bad at creating nice GUIs this pushes me to the area, with which I am totally uncomfortable, and makes me improve the related skills. Even though not every product has GUI, there is always a public interface of some sort – for example, the API in case of libraries – and the deliverable thing has to have it in a consisted, finished and polished state.
I have just said that the key feature of shippable products is that they have to be finished at some point, but at the same time the work on them never stops. While we might imagine that after the thing is published developers can just relax and enjoy the results of their work, in reality this hardly ever happens, because once the product makes its way to the users someone has to support it. This particularly implies that jumping on the boat of shipping goods one takes the obligation to put a lot of effort into the project in long-term perspective. The things to do after the first version is released are more or less obvious: one has to fix bugs, help users with their problems, maintain the servers if there are some and maybe do some marketing. Additionally, as we remember, one could have rejected a number of feature proposals and it is a good time to reconsider them. In case of a pet-project, which never leaves your personal cave, you are not required to respond to feedback, fix issues and deliver updates, but if you chose to sell your creation (even in a figural sense) you won’t have any options – users hardly forgive ignoring them and their problems. This factor is very important because similarly to those listed above it makes one develop some self-discipline, make promises and work hard not to break them. Additionally, resolving issues found by users in a published application or tool is quite different from just fixing bugs in your internal code. First of all, customers will wait for fixes providing you another source of deadlines, but that’s not the most crucial part. The problem is that for any individual customer his or her issues are the only important thing, but you as a developer have to see the whole picture and prioritize your work accordingly – so that the critical problems, including those which are invisible to the users at the moment, are solved first. In comparison to this, fighting bugs in our private code is sort of a delightful thing. Really, you can take the most interesting bug and go fix it. If it doesn’t work, take another one and do something about it, or just don’t pay attention to problems at all if they cease to be a source of fun. Fortunately, this is not the option for the public products and with them you have to carefully choose what to fix, when to do it and what to tell customers about the problems which stay in there for weeks.
Finally, since I mentioned public relations, there is another aspect of delivered applications and libraries, which makes them a good thing to work on – they can get into your resume. To be honest, you can show your potential employer whatever code you have written – no matter what was its purpose. Nowadays this is especially easy thanks to source code repositories services like Github and Bitbufcket, which make showing off one’s programming skills a matter of several clicks. At the same time, the released products can serve much better demonstration of what you are capable of due to a range of reasons. The key idea here is that showing that you can not only implement your ideas in code, but also push them far enough to produce goods of some kind and make them available to the public would allow your interviewer to see that you are quite a disciplined fellow (yes, I truly believe that discipline is very-very important). Moreover, the fact that you have succeeded at bringing the results of your work to customers lets your future employer see that you are familiar with a broad range of problems and aspects of software development, which go far beyond the level of code. So, while from the standpoint of some employers there may be negative aspects of having a dozen of iOS apps on your resume, I believe most of them see the ownership of several released products as a sign of discipline, responsibility and developed skills – something that they look for in candidates.
Overall, the decision to deliver something that you like to work on helps you get much broader experience than just experimenting with code and seeing how far you can push it. To create a shippable product you usually have to develop and show a great deal of self-discipline, which can also be viewed as the ability to make and fulfill promises. You also put yourself in a situation where you absolutely have to communicate with other people, thus improving related skills – maybe even those of marketing your product, at which I am, for example, utterly bad. On the other side, communication caused by your determination to help users get the best from the product allows you to view the results of your efforts from different angles, which is almost impossible when no one apart from you sees what you create. Getting feedback might be difficult not only because portions of it can be negative and drowning, but also because to have it one has to pursue it actively and talk to strangers. While I find it hard to push myself to something like that, I also see that the key reason of these difficulties are various fears: fear of not fetching audience, fear of others saying that what took me weeks to create is utter crap and, yes, fear of looking like an idiot. The attempts to deliver something make you leave the comfort zone, fight all these fears and finally show both yourself and others what you are capable of.