Archive for July, 2009
Eclipse Productivity Shortcuts
Back in college, I used to be a notepad nazi, so as to say. I used to code all my giant programs solely in notepad (The most I upgraded to was to Textpad). And once I joined Google, I was apathetic to IDEs, so I just picked IntelliJ and went with it. Somewhere down the line, I attended a Testing and Refactoring workshop, and the only IDE available was Eclipse. And it was for a great reason.
While the focus of the workshop was testing and refactoring, what they did do, which I applaud them for, was they showed us some awesome shortcuts. And suddenly, I was doing these insane refactorings at the blink of the eye. It was then that I started searching for and learning every eclipse shortcut that would help me be more productive. And before I knew it, I was typing 6 words a minute and coding up 100 words a minute
. And I loved it.
And so, today, I just wanted to share the best shortcuts that make life easier. And without further ado :
Ctrl + Space : One of the two most important keyboard shortcuts that eclipse offers. This one is probably commonly known for autocomplete in eclipse, but not many people know that it is also context sensitive. For example, hitting Ctrl + Space when you are in the middle of typing will show you all members and methods that begin with your text. But hitting Ctrl + Space when you have nothing typed shows you all members and properties available. But the real eclipse masters know that, hitting Ctrl + Space when you type in for or foreach will show you autocomplete options for generating a for loop or for each loop. And if you do it right after you assign something to a collection or a list, it will fill in the loop variables for the for each loop. Autocomplete after typing in test, will allow you to generate the skeleton of a JUnit test case method. Autocomplete after typing in new, generates you a skeleton for a new call, which you can tab through and fill in. So many more uses and use cases for Ctrl + Space that can be found. You can generate / override method signatures in child classes. Just use and abuse it, and you will learn so much.
Ctrl + 1 : If there is just one more shortcut you remember from this post, let it be this one. The other super awesome, context sensitive shortcut in Eclipse, which is basically Quick Fix. If you have an error in a line, Ctrl + 1 will show you potential options to fix it, like importing a class, or adding an argument to a method or fixing the method signature. If you just do a method call which returns something, then you can hit Ctrl + 1 and ask it to assign it to a new local or field variable. You can hit Ctrl + 1 on a parameter to a method and assign it to a field. Ctrl + 1 on a variable can allow you to inline it, and on an assignment, can allow you to split up the declaration and assignment, or convert it to a field, parameter, etc. It is, by far, The Most Awesome Keyboard shortcut that you can know and use. Especially on errors!
Ctrl + F11 : Reruns the last run configuration that was executed. If you do TDD, then Alt + Shift + X, T followed by Ctrl + F11 is the most standard approach.
Ctrl + Shift + R : Shows the Open Resource dialog. Type to filter, and jump directly between classes. I love this shortcut, and use and abuse it!
Ctrl + Shift + O : Organizes Imports, and gets rid of unused imports.
Ctrl + O : Shows the methods and properties of a class. You can start typing to filter and hit enter to jump to a particular signature / type. Hitting Ctrl + O again toggles showing inherited members. Very useful for jumping between sections in a class, or finding that one method you want to get to.
Ctrl + T : Opens the Type Heirarchy. Shows all super classes as well as sub classes / implementing types in your class path. Very useful for jumping to an implementation class. Can be called from the class type, or even a method signature. Can toggle between Supertype and Subtype heirarchy if you hit Ctrl + T again. Again, you can type and filter once you are in this menu.
Ctrl + / : Comment / Uncomment code. Single or multiple lines, depending on what you have selected. Enuff said.
Alt + Shift + R : One of my most used shortcuts, Rename. It renames anything from variables to methods to even classes, renaming the class files if necessary. Also fixes all references to refer to it by the new name. Can sometimes break if there are compile errors, so watch out when you use it. You can also ask it to fix all textual references as well.
Alt + Shift + M : Extract Method. Super useful method to break up a larger method into smaller chunks. If the code block you have selected does not need to return too many types, and looks reasonable as a separate method, then pulls up a prompt where you can basically edit the method signature, including return type, method name and order and type of parameters. Very useful
Alt + Shift + C : Only useful when the cursor is on a method signature, but this one allows you to refactor and change the method signature. This includes changing the return type, method name, and the parameters to the method, including order, and default values if you are introducing a new one. Automagically fixes all references to said method.
Alt + Shift + L : Once you have a expression selected (a method call, or whatever), then Alt + Shift + L extracts that to a local variable. It prompts you for the name of the variable, and automatically infers the type as best as it can. Extremely useful shortcut!
Alt + Shift + Up / Down : This one is a useful one. If you hit up, it selects the next biggest code block, down selects the next smallest. Useful in conjunction with refactoring shortcuts like extract local variable, extract method, etc. Useful to know.
Alt + Shift + T : Brings up the Refactor menu. Depending on the context, this will show options like Rename, Move, Extract Interfaces and classes, Change Method Signature, etc. Nice to know, but not one I use very often. The ones I do use have already been listed above.
Alt + Shift + S : Shows the Source menu. This includes menu options like Comment related, and the ever useful Override / Implement Methods, Generate Getters and Setters, and much more. Some of the menu options have direct shortcuts, but a lot of the generate commands don’t, so useful to know.
Alt + Shift + X : Pulls up the Run menu, and shows what key you have to press to run a particular type. Now I generally use this as Alt + Shift + X, followed by T, which basically executes a JUnit Test. Fastest way to run unit tests without leaving the comfort of your keyboard.
Alt + Up / Down : Moves a block of lines up or down. Rather than say, selecting, hitting Ctrl + X and then going to the place and pasting, why not just select all the lines, and use Alt + Up or Down to move them. Automatically handles indentation depending on the block. Very convenient
Ctrl + D : Nice and Simple, deletes the current line the cursor is on. If you have selected multiple lines, then they are all blown away. Much faster than selecting a line and hitting delete.
UPDATE: Adding in some of the shortcuts that I forgot or were mentioned in the comments for easy finding
Ctrl + L : Jump to a Line number
Ctrl + Shift + T : Display available types. A better version of Ctrl + Shift + R if you are only looking for Java classes
Alt + Shift + Up / Down : Duplicate selected lines above or below. Easier than hitting Ctrl + C followed by Ctrl + V
Ctrl + Alt + H : This one, I didn’t know about. but pulls up the Call heirarchy, showing you all callers and users of the method under the cursor. Super useful, especially if you are refactoring.
Ctrl + Shift + L : Show the list of shortcuts. You can hit it again to go in and edit your shortcuts.
What could be done to improve CS Degrees (Part 2)
Continuing on from last time, this time, I want to focus on what could be done in colleges. What courses could be taught, and what is wrong with the industrial approach as well. Again, all of these are my opinions, formed from my experiences, so yours might differ.
Why can’t there be a course which teaches you how to write maintainable software ? Concepts like separating your concerns, reducing your coupling. Using interfaces as and when necessary to abstract out unnecessary details. How about a semester or two semester long class which gives a student a chance to develop something in the first semester and maintain, add new features to it in the second. The only times I have heard of this happening is with independent studies.
And how can we forget about unit tests? This concept was rarely (if at all) touched upon during my four years in college. The only reason I had even heard of the concept was because I had participated in the Microsoft Imagine Cup and the Top Coder competitions. It sure wasn’t mentioned or required in any of my courses. Looking back, I just wonder how much easier a lot of my projects would have gotten if I had just written unit tests instead of trying to trace and debug it manually. But instead, I don’t remember it as more than a honorable mention in my Software Engineering class.
Why is such a fundamental cornerstone of software development not given more focus in college? Ideally, there would be a dedicated course talking about testing, the various aspects and kinds and when and where it could be applied. Along with practical examples and usages and projects where different kinds of tests were required. In addition, each class like Algorithms, OOAD and even Database Design would require testing of some sort of the other. Professors and TA’s could just run the submitted code against some unit tests to check for validity and only have to manually look at the code for stylistic errors or for problems.
How many fresh graduates actually get to work on something completely new and exciting? Instead, most end up joining companies which have a large and existing code base. And let me tell you, working with legacy code is rarely, if ever, fun. But guess what, this is again not touched upon in college? Working with legacy code? You are on your own again. Why? This is such a fundamental aspect of being a software developer, yet its not a skill which is even touched upon in colleges. Even letting students loose on open source projects and asking them to contribute a patch or two is good experience, but we don’t do it.
Even the industry seems to be misleading in that sense. In most of my interviews, I was asked algorithmic questions. Sure, they were nice and tough to chew on, and they give a nice, contained question that the interviewees can code up. But think about it. When was the last time a developer had to write just one method? Isn’t the requirement more often than not developing a system or contributing to one? Why don’t we ask questions which test for this? I myself have started asking design questions which test, say, a candidate’s understanding of polymorphism by asking him to design a class structure to represent mathematical operations like addition, subtraction with two methods, evaluate() and toString(). Does the candidate understand how to use inheritance, or does he end up using conditionals and switch cases instead.
It just seems to me that colleges have, to an extent, lost track of what the industry needs, and the industry doesn’t seem to be helping its cause. Introducing some of the courses I outlined above, or even incorporating it into existing coursework would give prospective graduates a leg up when they look for jobs. Its setting them up for success, and we all want them to succeed.
Whats lacking in CS Degrees nowadays (Part 1)
I remember when I was a fresh grad, just joining Google. I was naive, starry eyed, and somehow scraped through the gauntlet of interviews thrown my way. Then came my first few weeks at work. I was given the task of writing this new testing framework for my product. In Java. Being the slinger that I am, I was in my zone. I worked for about three weeks, and churned out the code in no time. I had a working prototype which performed all that it needed to, and was customizable. I was pumped. And then came the point where I had to check this in. So of course, I sent it to one of the senior developers for review. And the first set of comments came back.
It almost seemed like there was a line of comment for each line of code I had sent. Suddenly, my starter project seemed like an insurmountable task. I ended up pairing with aforementioned developer, and refactoring the code till it was almost unrecognizable. But the end product after all that blood and tears and refactoring was something much more manageable and maintainable. We added unit tests for each component, and separated our concerns properly.
First, I thought maybe it was just me, I hadn’t learnt something in college. It was a humbling experience, and showed that I had much to learn. But then I saw this repeat. An intern I knew spent his entire internship developing a component for a bigger project, but he was unable to check it in till his internship finished. The code was simply horrible to maintain for anyone who had not written it, and there were no unit tests, so no additions could be done with confidence that nothing else was broken. This was code developed by a really smart guy, who was a pretty good programmer. And this was no isolated case, something along these lines happened again and again. So what happened ?
This was when I started questioning if what happened with me and this intern weren’t just isolated cases but part of something bigger? A conspiracy even? Well, I wouldn’t go so far, but simply put, why weren’t we taught in college how to actually develop software? Why doesn’t Software Engineering actually teach how to write maintainable, well tested applications? Why isn’t there a single CS course which taught us how to work with legacy systems?
I mean, the usual Computer Science degree consists of courses in Discrete Mathematics, Automata Theory, Data Structures and Algorithms, Object Oriented Analysis and Design, Software Engineering and many more. And sure, I learnt about how to define classes in my OOAD class, and how to write sorting algorithsm and graph algorithms in my Algorithms class, and what the different steps for a Software project are and what approaches are present in my Software Engineering class. But looking back at it, none of them really prepped me for the work I would do in real life.
For instance, the OOAD class had a great project of creating a Chess game with AI. And I am proud to say I did get it working with a pretty solid AI backing it. But it was not code that I am proud of, nor would I ever want to go back and add a feature or fix a bug in it. My Software Engineering class had a project which was mostly talk and design, and really not that much implementation. And Algorithms was mostly write a function or one or two classes to implement an algorithm.
These were some great professors. And I gained a solid theoretical base in Algorithms and OOAD which would have been impossible otherwise. But some of these professors had industry experience. And the assignments they gave and the problems they assigned reflected nothing of that. And that hasn’t been just my experience, restricted to my university. Talking to my colleagues and friends who graduated around the same time, it has been the norm, not the exception. Why is this the case? Why couldn’t my CS degree have prepared me for what I would have to work with?
I will continue down this line of thought in my next post, where I try to articulate what I would have wanted to be taught in college, knowing what I do know now.
The ROI of Testing
Nowadays, when I talk with (read: rant at) anyone about why they should do test driven development or write unit tests, my spiel has gotten extremely similar and redundant to the point that I don’t have to think about it anymore. But even when I do pairing with skeptics, even as I cajole and coax testable code or some specific refactorings out of them, I wonder, why is it that I have to convince you of the worth of testing ? Shouldn’t it be obvious ?
And sadly, it isn’t. Not to many people. To many people, I come advocating the rise of the devil itself. To others, it is this redundant, totally useless thing that is covered by the manual testers anyway. The general opinion seems to be, “I’m a software engineer. It is my job to write software. Nowhere in the job description does it say that I have to write these unit tests.” Well, to be fair, I haven’t heard that too many times, but they might as well be thinking it, given their investment in writing unit tests. And last time I checked, an engineer’s role is to deliver a working software. How do you even prove that your software works without having some unit tests to back you up ? Do you pull it up and go through it step by step, and start cursing when it breaks ? Because without unit tests, the odds are that it will.
But writing unit tests as you develop isn’t just to prove that your code works (though that is a great portion of it). There are so many more benefits to writing unit tests. Lets talk in depth about a few of these below.
Instantaneous Gratification
The biggest and most obvious reason for writing unit tests (either as you go along, or before you even write code) is instantaneous gratification. When I write code (write, not spike. That is a whole different ball game that I won’t get into now), I love to know that it works and does what it should do. If you are writing a smaller component of a bigger app (especially one that isn’t complete yet), how are you even supposed to know if what you just painstakingly wrote even works or not ? Even the best engineers make mistakes.
Whereas with unit tests, I can write my code. Then just hit my shortcut keys to run my tests, and voila, within a second or two, I have the results, telling me that everything passed (in the ideal case) or what failed and at which line, so I know exactly what I need to work on. It just gives you a safety net to fall back on, so you don’t have to remember all the ways it is supposed to work in. Something tells you if it is or not.
Also, doing Test Driven Development when developing is one of the best ways to keep track of what you are working on. I have times when I am churning out code and tests, one after the other, before I need to take a break. The concept of TDD is that I write a failing test, and then I write just enough code to pass that test. So when I take a break, I make it a point to leave at a failing test, so that when I come back, I can jump right back into writing the code to get it to pass. I don’t have to spend 15 – 20 minutes reading through the code to figure out where I left off. My asserts usually tell me exactly what I need to do.
Imposing Modularity / Reusability
The very first rule of reusable code is that you have to be able to instantiate an instance of the class before you can use it. And guess what ? With unit tests, you almost always have to instantiate an instance of the class under test. Therefore, writing a unit test is always a first great step in making code reusable. And the minute you start writing unit tests, most likely, you will start running into the common pain points of not having injectable dependencies (Unless of course, you are one of the converts, in which case, good for you!).
Which brings me to the next point. Once you start having to jump through fiery hoops to set up your class just right to test it, you will start to realize when a class is getting bloated, or when a certain component belongs in its own class. For instance, why test the House when what you really want to test is the Kitchen it contains. So if the Kitchen class was initially part of the House, when you start writing unit tests, it becomes obvious enough that it belongs separately. Before long, you have modular classes which are small and self contained and can be tested independently without effort. And it definitely helps keep the code base cleaner and more comprehensible.
Refactoring Safety Net
Any project, no matter what you do, usually ends up at a juncture where the requirements change on you. And you are left with the option of refactoring your codebase to add / change it, or rewrite from scratch. One, never rewrite from scratch, always refactor. Its always faster when you refactor, no matter what you may think. Two, what do you do when you have to refactor and you don’t have unit tests ? How do you know you haven’t horribly broken something in that refactor ? Granted, IDE’s such as Eclipse and IntelliJ have made refactoring much more convenient, but adding new functionality or editing existing features is never simple.
More often than not, we end up changing some undocumented way the existing code behaved, and blow up 10 different things (it takes skill to blow up more, believe me, I have tried). And its often something as simple as changing the way a variable is set or unset. In those cases, having unittests (remember those things you were supposed to have written?) to confirm that your refactoring broke nothing is godsend. I can’t tell you the amount of times I have had to refactor a legacy code base without this safety net. The only way to ensure I did it correct was to write these large integration tests (because again, no unit tests usually tends to increase the coupling and reduce modularity, even in the most well designed code bases) which verified things at a higher level and pray fervently that I broke nothing. Then I would spend a few minutes bringing up the app everytime, and clicking on random things to make sure nothing blew up. A complete waste of my time when I could have known the same thing by just running my unit tests.
Documentation
Finally, one of my favorite advantages to doing TDD or writing unit tests as I code. I have a short memory for code I have written. I could look back at the code I wrote two days ago, and have no clue what I was thinking. In those cases, all I have to do is go look at the test for a particular method, and that almost always will tell me what that method takes in as parameters, and what all it should be doing. A well constructed set of tests tell you about valid and invalid inputs, state that it should modify and output that it may return.
Now this is useful for people like me with short memory spans. But it is also useful, say, when you have a new person joining the team. We had this cushion the last time someone joined our team for a short period of time, and when we asked him to add a particular check to a method, we just pointed him to the tests for that method, which basically told him what the method does. He was able to understand the requirements, and go ahead and add the check with minimal handholding. And the tests give a safety net so he doesn’t break anything else while he was at it.
Also useful is the fact that later, when someone comes marching through your door, demanding you fix this bug, you can always make sure whether it was a a bug (in which case, you are obviously missing a test case) or if it was a feature that they have now changed the requirements on (in which case you already have a test which proves it was your intent to do it, and thus not a bug).
Separation anxiety ?
We all have separation anxiety. Its a human tendency. We love inertia, and we don’t like change. But why should your code have separation anxiety ? Its not human (even though it might try and grow a brain of its own at times)!
I bring this up because I got the chance to work with someone who had some questions on how to test UI code. Fairly innocuous question, and in most cases, my response would have been, keep the UI code simple and free of any logic, and don’t worry too much about it. Or you could write some nice end to end / integration tests / browser based tests. So with that response set in mind, I set off into the unknown. Little was I to know was that was the least of my concerns. As I sat down to look at the code, I saw that there were already tests for the code. I was optimistic now, I mean, how bad could things be if there are already tests for it ?
Well, I should remember next time to actually look at the tests first. But anyways, there were tests, so I was curious what kinds of tests they wanted to write and what kind of help I could provide, if any. So it turns out, the class was some sort of GUI Component, which basically had some fields, and depending on whether they were set of not, displayed them as widgets inside of it. So there were, say, 5 fields, and differing combinations of what was set would produce different output. The nice thing was that the rendered data was returned as a nice Java object, so you could easily assert on what was set, and get a handle on the widgets inside of it, etc. So the method was something along the following lines :
public RenderedWidgetGroup render() { RenderedWidgetGroup group = createWidgetGroup(this.componentId, this.parent); if (this.name = null) { return group; } group.addWidget(new TextWidget(this.name)); group.addWidget( new DateWidget( this.updatedTimestamp == null ? this.createdTimestamp : this.updatedTimestamp)); return group; }
So far, so good, right ? Nice, clean, should be easy to test if we can set up this component with the right fields. After that, it should just be a few tests based on the different code paths defined by the conditionals. Yeah, thats what I thought too. So, me, being the naive guy that I was, said, yeah, that looks nice, should be easy to test. I don’t see the problem.
Well, then I was taken to the tests. The first thing I see is a huge test. Or atleast thats what I think it is. Then I read it more closely, and see its a private method. It seems to take in a bunch of fields (Fields with names that I distinctly remembered from just a while ago) and churn out a POJO (Plain Old Java Object). Except this POJO was not the GUI Component object I expected. So obviously, I was curious (and my testing sensors were starting to tingle). So I followed through to where it was called (which wasn’t very hard, it was a private method) and lo and behold, my worst fears confirmed.
The POJO object generated by the private method was passed in to the constructor of the GUI component, which (on following it further down the rabbit hole) in its constructor did something like the following :
public MyGUIComponent(ComponentId id,
Component parent,
MyDataContainingPOJO pojo) {
super(id, parent);
readData(pojo);
}
And of course, readData, as you would expect, is a :
- Private method
- Looks through the POJO
- If it finds a field which is not null then it sets it in the Gui Component
And of course, without writing the exact opposite of this method in the unit test, it just wasn’t possible to write unit tests. And sudddenly, it became clear why they were having trouble unit testing their Gui Components. Because if they wanted to test render (Which was really their aim), they would have to set up this POJO with the correct fields (which of course, to make things more interesting / miserable, had sub POJOs with sub POJOs of their own. Yay!) to be exercised in their test.
The problem with this approach is two fold :
- I need tests to ensure that the parsing and reading from the POJO logic is sound, and that it correctly sets up the GUI Component.
- Every time I want to test the render logic, I end up testing (unintentionally, and definitely unwantedly) the parsing logic.
This also adds, as I saw, obviously complicated pre test setup logic which should not be required to test something completely different. This is a HUGE code smell. Unit testing a class should not be an arduous, painful task. It should be easy as setting up a POJO and testing a method. The minute you have to perform complicated setup to Unit test a class (Note, the keyword is unit test. You can have integration tests which need some non trivial setup.), stop! There is something wrong.
The problem here is that there is a mixing of concerns in the MyGuiComponent class. As it turns out, MyGuiComponent breaks a few fundamental rules of testability. One, it does work in the constructor. Two, it violates the law of demeter, which states that the class should ask for what it needs, not what it doesn’t need to get what it needs (Does that even make sense ?). Thirdly, it is mixing concerns. That is, it does too much. It knows both how to create itself as well as do the rendering logic. Let me break this down further :
Work in the constructor
If you scroll back up and look at the constructor for MyGuiComponent, you will see it calling readData(pojo). Now, the basic concept to test any class is that you have to create an instance of the class under test (unless it has static methods. Don’t get me started on that…). So now, every time you create an instance of MyGuiComponent, guess what ? readData(pojo) is going to get called. Every. Single. Time ! And it cannot be mocked out. Its a private method. And god forbid if you really didn’t care about the pojo and passed in a null. Guess what ? It most probably will blow up with a NullPointerException. So suddenly, that innocuous method in the constructor comes back to haunt you when you write yours tests (You are, aren’t you ?).
Law of Demeter
Furthermore, if you look at what readData(pojo) does, you would be even more concerned. At its base, MyGuiComponent only cares about 6 fields which it needs to render. Depending on the state of each of these fields, it adds widget. So why does the constructor ask for something totally unrelated ? This is a fundamental violation of the Law of Demeter. The Law of Demeter can be summed up as “Ask for what you need. If you need to go through one object to get what you need, you are breaking it.”. A much more fancier definition can be found on the web if you care, but the minute you see something like A.B().C() or something along those lines, there is a potential violation.
In this case, MyGuiComponent doesn’t really care about the POJO. It only cares about some fields in the POJO, which it then assigns to its own fields. But the constructor still asks for the POJO instead of directly asking for the fields. What this means is that instead of just creating an instance of MyGuiComponent with the required fields in my test, I now have to create the POJO with the required fields and pass that in instead of just setting it directly. Convoluted, anyone ?
Mixing Concerns
Finally, what could be considered an extension of the previous one, but deserves a rant of its own. What the fundamental problem with the above class is that it is mixing concerns. It knows both how to create itself as well as how to render itself once it has been created. And the way it has been coded enforces that the creation codepath is executed every single time. To provide an analogy for how ridiculous this is, it is like a a Car asking for an Engine Number and then using that number to create its own engine. Why the heck should a car have to know how to create its engine ? Or even a car itself ? Similarly, why should MyGuiComponent know how to create itself ? Which is exactly what is happening here.
Solution
Now that we had arrived at the root of the problem, we immediately went about trying to fix it. My immediate instinct was to pull out MyGuiComponent into the two classes that I was seeing. So we pulled out a MyGuiComponentFactory, which took up the responsibility of taking in the POJO and creating a GuiComponent out of it. Now this was independently testable. We also added a builder pattern to the MyGuiComponent, which the factory leveraged.
class MyGuiComponentFactory { MyGuiComponent createFromPojo(ComponentId id, Component parent, MyDataContainingPOJO pojo) { // Actual logic of converting from pojo to // MyGuiComponent using the builder pattern } } class MyGuiComponent { public MyGuiComponent(ComponentId id, Component parent) { super(id, parent); } public MyGuiComponent setName(String name) { this.name = name; return this; } }
And now, suddenly (and expectedly, I would like to add), the constructor for MyGuiComponent becomse simple. There is no work in the constructor. The fields are set up through setters and the builder pattern. So now, we started writing the unit tests for the render methods. It took about a single line of setup to instantiate MyGuiComponent, and we could test the render method in isolation now. Hallelujah!!
Disclaimer :
No code was harmed / abused in the course of the above blog post. There were no separation issues whatsoever in the end, it was a clean mutual break!
Recent putbacks