sábado, 17 de octubre de 2020

Android Alebrijes - Dealing with legacy code.

Alebrijes are brightly colored Mexican folk art sculptures of fantastical creatures. Alebrijes are very strange and unknown animals.

A new user story comes for grooming, apparently a very small change, but as part of the requirements you have to change the legacy class, yes that class that no one wants to touch and everyone is scared of, sounds familiar? After reading the story, everyone agreed on 3 points, you think you can do it faster, but you want to be cautious so you say 3.

When the sprint starts you are very excited to do the change, you open the code, and boom, you found an alebrije. What the falafal is going on here?, this story requires more things than I initially thought, how I will be able to finish this? and I’m not even able to understand the code.

Wait, how did we end up with this implementation? Why the code is written in this way? Ummm, there are multiple reasons why this piece of falafal ended up like this, but now is not the time to find a culprit; as one of my managers use to say, “you touch it, you own it” or “Es tu perro y tu lo bañas”, now you are the owner of this code and you are responsible for this.

Let’s be honest, every single project around has code like this, a lot of code is already a mess, and we need to learn how to live with it, so the real question is what can we do to make it better? How can we improve the quality of this code?

Every situation is different, and there is no silver bullet to deal with this mythical beasts, but let’s start with the premise that you got a very old piece of code with zero documentation, zero unit testing, and not following the architecture patterns, conventions and best practices for Android. With that in mind here are some of the things that you can do:

Improving Documentation 

How much documentation do we need? Only whatever you can keep updated. Keep it simple, but not too simple. Add enough detail to understand how the implementation works.

Start by creating a simple diagram. It can be a simple diagram with boxes and their relationships. This will help to understand what components are involved. If the authors of the code are still available, involve them.

After the basic diagram, you can create a navigation flow, a high-level class diagram, and sequence diagrams to understand the flow, dependencies, behaviors, and responsibilities of each component.

When the feature includes complex business logic, use the Debugger and logger to understand it better. Document all your findings.

Start documenting the code

  • Public methods. Start with public methods. Those are the ones expose to external invokers and require good documentation.
  • Exceptions. Document possible exceptions to be thrown by methods.
  • Executable specifications through unit testing. This will continuously increase with each iteration. Try to follow a pattern where we clearly specify the scenarios under test and the expected behavior. One popular naming convention Should_ExpectedBehavior_When_StateUnderTest.

Make a list of to-do items to improve the code. TODOs can be included in the code or using some wiki page. Next time someone has some free time, they can come to the list and pick one of the items.

Improving Estimation

Don’t shout yourself in the foot, be prepared ahead of the grooming. You need enough time to work on legacy code. We need to be as accurate as possible. We don’t want to introduce more technical debt or make the code worst.

Start by reading and understanding the user story.

Identify the changes needed to accomplish the new functionality.

When the story has a big impact on the code, split it into small to-do tasks.

Estimate the required tech tasks to complete the user story. Don’t forget to include integration testing or data preparation when needed.

Improving Testing

Without tests, there is no way to tell if we are breaking existing functionality. Don’t trust code, not including tests.

But where do I start if most of the code is in the views, in private methods, static functions, and final classes?

Robolectric

Robolectric lets you run view tests without an emulator or physical device. This will help you to write tests for the views without installing the app. You can test activities or fragments in isolation. Robolectric extends Android framework with a large set of test APIs. Robolectric uses the concept of shadows to extend the behavior of an Android OS component. You can create your own custom shadow implementations.

Kotlin and Mockk

With the help of Kotlin and Mockk you should be able to test static utility methods, static initializers, final classes, private methods. Powerbock is a really good option if you are allowed to use only java.

Improving the code Quality

We can start with small refactors to improve the readability and maintainability of the code. We can start with changes like renaming classes, variables, and methods. This will help us to get a better understanding of the implementation so we can proceed with bigger refactors.

Please make small PRs when making your changes. If you send a big PR, is very likely that reviewers will not be able to follow the changes. Additionally, include in the PR description the problem you are trying to solve, and the solution.

Problem/Requirement

Include a description of the problem or requirement to solve

Solution

Description of the solution

Refactoring

The next refactors will require a full regression testing by your QA, be very careful about when to do these changes.

  • Separate UI logic from application logic. Move logic outside of the Views. Nowadays we have MVP, MVVM, MVI, but all of them have the same intent Separation of Concerns. Try to keep the view classes lean to avoid life-cycle related problems.
  • Life Cycle Aware components. Move logic triggered by lifecycle events out of the activity/fragment. This will help you to keep your code more organized and maintainable.
  • Use LiveData and Flow to notify data changes to the View.
  • Use Coroutines to simplify your background operation handling.
  • Move data access logic to repositories.
  • Extract code to new classes using kotlin. Kotlin will help to simplify and made the code safer with java support.
  • Use DI. Encapsulate related behavior and expose it using interfaces. This will help you with the tests.

Architecture Components and Guide to App architecture

Android already has a guide with the best practices and recommended architecture to help you design robust, testable, and maintainable apps. You don’t need to reinvent the wheel, use the Android guide to App Architecture and Architecture Components collection library. The code works consistently across Android versions and devices so that we can focus on the related to our business domain.

Follow the Boy scout rule

We keep doing small changes to the code to improve it. The code gradually will get better and better. With this rule, we will see the team caring for the system as a whole, rather than individually caring for the parts they build.

And that’s all, I hope little by little we get rid of those alebrijes, and we don’t add more technical debt during the process :).

domingo, 4 de octubre de 2020

Are you a good Software Developer?

Are you a good Software Developer? Recently I heard this question and it really caught my attention.

How can we answered this? are we good because we do our testing? because we pass the sonar quality gates? because we finish our tasks on time? or based on production statistics like app rating, or existing bugs? 

Well, tools and reports will definitely help, but I think is also based on expectations. 

I still remember when I heard someone having big expectations from an specific developer. Was he able to fulfill them? Not sure.  

I think the same developer can have a different evaluation depending on whom you are asking. the client, the PO`s, the manager, the architect. 

The true is, We can not ignore those expectations. So let's focus on some of the most common expectations for a Software Developer in the job market. At the end the companies are looking for good Software Developers right? Do we really know what we are signing for?

Problem Solver and analytical skills

Here, We can have technical, and not technical problems. It refers on how we overcome the problems, on how we response to different situations.

So, we get a problem, we set a plan, we execute that plan, and finally we evaluate the results.


But wait, Is the problem even solvable? Did we find the root cause? Is the solution solving the actual need? Did we check the whole impact of the solution? Did we include all the involved parties?


Communication Skills


This very important because we are supposed to work in a team. We also need to stand up to our ideas, suggestions. We need to also interact with not technical people without jargon. If we want to succeed, Is not enough being brilliant, we need to clearly communicate our ideas.


Passion


Sometimes doing software development can be quite stressful. Long meetings, constant changes with rigid deadlines, dependencies with multiple teams with a different commitment to the project, or pressure when critical production defects are found.


And depending on the company you work for is highly possible you don't have a social life.


All of these can be enough to quit being a Software Developer, but If you haven't let's answer these questions: Do you feel satisfied doing this or would you rather being doing something else? Are you proud of your work? Do you stick to only doing your work? Do you feel motivated to keep learning new technology? If you don't have passion is ok, as long as you keep giving results.


Do you go with the best possible solution?


I want to clarify that not everything is bad about being a Software Developer, there are a lot of cool things about it, but we can have those cool things for some other discussion.


Continuous learning


Willingness to keep learning new skills, new technology, new programming languages.


Includes being aware of the latest Software development practices


Learning can come from multiple sources like:

  • Books, Blogs.
  • Individual courses.
  • Coding boot camps. Some of them provide a mentor for some months. They will guide you to speed up your learning in the selected technology.
  • Codelabs. I really like Android Codelabs.
  • Joining software open projects.
  • Find a mentor. 
  • Conferences, Meetups.
  • 1 on 1 with your manager. I have found this very useful. 


Team player


Is impossible to work alone these days. We are in constant collaboration, and We need to work on the relationships with the other team members.


I have seen amazing engineers not able to succeed in a company because they were unable to integrate with other teams. But that was also as result of lack of communication skills.


Being a good team player means helping to create a collaborative and positive working environment.


Don't being arrogant because you are the most senior developer. It means being humble. We always learn something from each other. We are all responsible for the project(s).


When the team succeed we celebrate, when the team finds some problem, we solve it together.


Are you helping others to succeed? Do you get satisfaction when the teams improved?


Are the team members happily coming to you when they have a question?



Shared knowledge


Mentoring other developers is a very important task in a project. Additionally, when you try to explain something, you know if you really understand the concept.


Are you Collaborating with ideas to improve the code, or the existing processes?


Are you engaged with software communities?


Do you share your knowledge writing Blogs? through code reviews?


Are you teaching by example?



Time/Task management. Achieve results


Can you do multitasking? Are you able to prioritize and work on the most important at the moment?

How accurate are yous estimations?

Can you manage details and keep sight of multiple projects?

Adapt to changes in requirements, and exploring new solutions.

Are you delivering quality results? are they on time?


These expectations will give us an idea of some of the most common expectations for a Software Developer in the market. But what about yourself, how do you feel? what is your personal feedback? are you a good Software Developer?


Having said that, I think I'm a good developer, but I'm not completely satisfied with what I have been doing, I still have a lot of things to improve. :)