Revisiting Java Code Reviews
Coffee. Chocolate. A good ol’ cup of tea. Food or otherwise, we all have those home comforts that instill a feeling of coziness. The little things that give you a warm fuzzy feeling when curled up on the couch in times of joy or strife. Technologists commonly exhibit similar attachments to programming languages and frameworks.
Programmers develop a technical comfort zone for languages and frameworks that are as inviting as a cup of tea
Be it Java, Haskell or Typescript, nothing gives you a higher feeling of elation than being in the coding zone using your comfort blanket language. Coupled with your favourite IDE, solving problems in the comfort zone is immensely gratifying.
With my recent role change I’ve been forced out of my Typescript comfort zone. Moving to a product focused role has meant I’ve had to dust off my Java skills and review team changes. With me completing my last from scratch feature 7 years ago, it has proven difficult. This week I reflect on the challenges of reviewing code in unfamiliar languages, and how my experiences can help you re-adjust.
Wake Up And Smell the Coffee
Technology evolves rapidly. Programming languages and frameworks are no exception. One such example that has been close to my heart over the last 3 years is the evolution of Angular. From Angular JS to the upcoming Angular 7, I have used the majority of these versions. Each contained a host of new features. The JS rewrite in particular resulted in a significant learning undertaking for developers.
Lack of experience with new language features leaves you playing catch up. One of the major features used extensively by our team that I bypassed is Java streams. This enhancement introduced in Java 8 allows for adoption of a functional style. I can safely say this has been one of the constructs that I’ve had to invest considerable time investigating.
Another strategy that can help is drawing parallels with technologies recently used within your comfort zone stack. Within the Web domain, similarities to both Lodash and RxJS Observable pipes have helped me adapt to Java streams. Your experiences with all languages will help you grow and adapt to new technology more quickly.
Clouds In My Coffee
Coding involves an element of pattern matching. Think back to an internship, or your first role. At that time, you were most likely more humble. You were comfortable acknowledging that you didn’t know everything. If your experiences were anything like mine, there was a lot of online searching and combing of forums such as Stack Overflow to find your desired answers. Another strategy to acclimatise to unknown code bases is to replicate any common patterns that you detect. The latter is one I’ve seen our interns adopt more recently.
In different languages, there’s a pattern, there’s a pattern, there’s a pattern, there’s a pattern…
Heuristics such as Uncle Bob’s Clean Code guidelines and Martin Fowler and Kent Beck’s Code Smells translate across technologies. When adapting to repositories written in unfamiliar programming languages, not all patterns from your home code base will translate. File structure is one obvious example. Our Java code bases follows the Gradle structure. Meanwhile our UIs adopt a flat file system as per the Angular Style Guide. It is worth identifying the build frameworks used to develop an intuition on where code will live.
Class design patterns also differ. With years of Web and Desktop UI experience, structuring features using Model View Controller, or a related variant, is ingrained. I’ve had to acclimatise to the common REST service endpoint class composed of a dedicated response handler and DAO. Your friendly neighbourhood IDE can help greatly, especially the search and find definition functions.
There Might Be Coffee
Contemplating possible performance issues in unfamiliar languages is another issues I’ve faced. Identifying potential bottlenecks and concurrently issues is challenging at the best of times. I’ve always found that programmers struggle to write and understand concurrent code. It has certainly been a cause of some recent production issues. Throw in confusion regarding concurrent collections and locking mechanisms and these issues can be difficult to prevent.
Identifying bottlenecks and other performance issues is not easy in unfamiliar technologies
Without knowledge of language specific best practices, you’ll struggle to reason about performance outside general algorithmic complexity. Utilising various resources can assist you in your learning quest. Tools such as profilers can help you diagnose elusive bottlenecks. Also, seek out technical mentors to work through your ideas and concerns. Ideally have more than one to obtain differing opinions and to ensure help remains if your rock star mentor leaves. Reading can expose industry best practices. For Java specifically, I’ve added Java Concurrency in Practice by Brian Goetz et al to my reading list to continue my journey of enlightenment.
One More Cup of Coffee
Delving outside our technical comfort zones can be daunting. It is assumed that a technical lead will be able to lead across the stack. Some patterns do translate across the technical expanse. But others do not. Regardless, it is important to ensure unsuitable constructs and designs are not translated into the new technology. Such mistakes will affect readability, maintainability and system performance.
With our ongoing push for our technologists to become full stack developers, my recent experiences has proved enlightening. I’ve been able to empathise more with the key challenges our Java developers are facing as they learn Web technologies. It has given me more of an appreciation for the support managers need to provide programmers.
I hope my experiences allow me to lead by example. I’ve always wanted to encourage engineers to embrace diving into unfamiliar technologies. Only then shall we all evolve as technologists.
Thanks for reading!