Skip to Content

Category Archives: Project management

Remote work in pandemic times

One of the best things about working in the IT industry is that we are in a state of constant digital transformation, which means that we are able to use technology to adapt our processes and meet the high standards of a fast-paced world. 

It has been 7 weeks since we started to work entirely remotely at Tango, following the government’s recommendations to avoid the spread of the virus, but that doesn’t mean we are new in this game.

Just to add context, Tango has offered the possibility to work remotely, even before the pandemic situation. Consequently, we have been improving our process to manage distributed teams for the last decade. We know transitions to working remotely can strain your internal performance at the beginning if you’re not used to it, but it can help you get ahead of the curve.

You should be prepared for distributed teams, with or without the pandemic, for various reasons like increased productivity (35-40% more productivity), better quality (40% fewer quality defects), higher engagement rates (41% lower absenteeism), and higher profitability (21% higher) (Forbes, 2020). All of these reasons are driving companies to go remote.

Given the benefits and the current situation, organizations are preparing to invest in remote teams more than ever, so we need to find a way to train ourselves to dive into this not-so-new way of working.

Here are 5 points that  I’d like to keep in mind each time that I need to work with distributed teams.

1. Trust isn’t negotiable: 

According to the research report “Why Trust is Critical to Team Success by Reina and the Center for Creative Leadership, trust is a must for you and your team. By building trust you can:

  • Deepen the engagement of your talent
  • Foster collaboration
  • Drive change

“Trust building helps teams step into the ambiguity, to stay committed to managing the unknown with confidence, and to embrace change as an opportunity to learn, grow, and do great work together.” (Rina, PhD, Reina, PhD, and Hudnut, MIA, 2017)

2. Communication is key:

The lack of communication can lead to the worst outcomes. N. Sharon Hill and Kathryn M. Bartol wrote an interesting article about communication that is worth giving a try: Five Ways to Improve Communication in Virtual Teams.

The book “From Chaos to Successful Distributed Agile Teams mentions:

The first principle for successful geographically distributed agile teams is to establish acceptable hours of overlap. The Key is enough communication time and sufficient communication tools.

According to Johanna Rothman and Mark Kilby, authors of “From Chaos to Successful Distributed Agile Teams.”, an agile team requires a minimum of four hours of overlap a day for sufficient collaboration. Teams without the possibility of adequate hours of overlap can avoid chaos if they follow an organized agenda.

3. I need a committed team:  

This is important to keep up with the Continuous Delivery model we are following at Tango. I need to know I can trust my team will get the job done.

Increasing commitment involves the two aspects we previously mentioned: Trust and communication, according to “The Five Dysfunctions of a Team (Lencioni, 2019), also adding the importance of healthy conflict, which drives commitment to decisions, avoids an environment where ambiguity prevails.

Lencioni mentions in his book how the lack of commitment can lead to the avoidance of accountability, which results in inattention to results.

4. We should be looking for continuous improvement:

The Institute of Quality Assurance defined continuous improvement as “a gradual never-ending change which is focused on increasing the effectiveness and/or efficiency of an organization to fulfill its policy and objectives”.

This definition does not exclude the growth of your team, and that should encourage you to seek the improvement of your organization by the gains of your team members.

A way to keep teams motivated is by showing them that failing is part of the learning process and success comes with a lot of failures. No one is going to hit you if you break the staging server; just rollback and check what happened, taking on the responsibility to determine what you missed. 

5. We should follow a methodology:

We decided to follow the Scrum methodology since it has worked the best for our team, but you can choose any methodology you think it’s most appropriate for your team. 

Using a methodology will allow you to understand your processes better, know your limitations, be consistent across your projects, and it will give you consistent metrics and expectations.

In case you are interested in the Scrum methodology, let me share our routine.

On Monday, we start with our Sprint Planning meeting, adding a quick standup to check what the team did during the last working day. All work must be ready and without missing details. The whole team follows the Definition of Ready and the Definition of Done, so we don’t have chunks of non-working products. We run 2-week sprints, following the Scrum methodology.

We have a standup from Tuesday to Friday and don’t use a camera at all unless it’s our Retrospective meeting (We like the feeling of privacy in our teams), and when we do have our Retrospective meeting, team members feel motivated to turn on the camera, so we all interact. 

Here are some practical tips I like to take into account when I approach any of my team members: 

  • Before calling my team, I ask myself: “Do I need to call them? Could a message or email be enough?”
  • Icebreakers to start, don’t take too long, but that would make any meeting run more smoothly.
  • When messaging your team, include the reason for the message right after the salutation. This is not rude, people’s time is essential, and just because you combine the greeting and a question doesn’t mean you don’t care about the person.
  • Agree on the best time to have a call. Unless it’s an emergency, it’s better to have an arranged call than to cold-call your team members.
  • If you create an event, always add the topic, so that everyone is aware of the discussion.
  • Be patient. We all have to deal with bad internet connections, interruption by our pets, family, and other external situations.



Remote work is no longer just a perk, in fact, it’s more like a way of living. Let’s be more intentional about how we work and show that we can still be productive while adding value to the work we do while being a remote team member. 

Productivity is a top concern for companies, but we found that working remotely actually makes us more productive overall. So, if you are in the process of transitioning to a distributed team, you can start by implementing some of the tips I shared here. 

As an additional benefit, remote work has allowed me to join worldwide teams that share work-related ideas, workshops, and helped me to continue growing as a professional.

Have you observed any similar situations in your remote working experience? Let us know in the comments down below.


0 1 Continue Reading →

How to conquer legacy code and not die trying

As a software engineer, I know how frustrating it can be to work with legacy code, especially when your client has no idea of the level of technical debt you are inheriting, and wants you to deliver bug fixes and new features as soon as possible. If you’re as passionate about software development as I am, you’re supposed to enjoy it, not hate it. That’s why I’m writing this blog post: To share my experience and a key piece of advice about how to deal with it.

The most common issues of working with legacy code are:

  • Having no tests at all, or no useful tests.
  • Outdated dependencies.
  • Poor software architecture.
  • Technical debt.
  • Lack of documentation.

Here are some recommendations about how to deal with it and not to die in the attempt.

Risk Assessment

After performing this assessment, you’ll be aware of all the risks you’re taking (or inheriting). In the end, you’ll have to decide how comfortable you are with the given risks. Therefore it’s super important to know the current state of the project and to be aware of what to expect when it’s time to get your hands on the code.

The goal of this assessment is to learn as much as possible of the current codebase. My recommendation is to focus on the following:

  • Documentation: Unfortunately, most of the time the only documentation that you might find in an existing project is the README file, and even worse, this file is usually not up to date. Look for architecture diagrams, wikis, or any other documentation that can help you to understand the codebase at a glance.
  • Test coverage: Speaking of documentation, tests are considered the best code documentation. You should check for the current test coverage, but more importantly, check the quality of the tests. Sometimes tests check against specific text instead of testing the business logic that drives that text to be displayed. If there are good quality tests, you should be able to have a better sense of the business logic, and moreover, the current architecture.
  • Dependencies: Having a ton of dependencies is not a good sign. I always try to avoid adding a new dependency unless it’s strictly necessary, or the benefits of said dependency exceed the cost of making it happen. Check how outdated dependencies are and how difficult it would be to do upgrades. Pay extra attention when it comes to deprecated versions and you need to do major upgrades.
  • Deployment process: A new feature, bug fix, or improvement is not considered done until it reaches the production environment. You need to understand what the deployment process is since you have to take this into account while giving estimations.
  • Backlog: After getting a little bit familiar with the codebase, you need to know what’s about to come. You might be asked to add a particular feature that might not be that easy to add given the current architecture or the version of the dependencies implemented. The value of knowing the backlog beforehand is to raise any warning flags in the early stages so that you can plan.After going through each of the above points, you should be able to communicate any risks to your client. Set clear expectations and decide whether to move forward or not based on your discoveries.

Buy insurance

If the test coverage isn’t the best, you should ask to work on adding tests before adding new features. You need to be confident enough that you’re not adding new bugs while changing the codebase, and the only way to be sure is to have a proper test suite. Good test coverage is your insurance as a developer.

Refactor on the go

I know that you might be tempted to do a major refactor as soon as you start touching the codebase; however, based on my experience, that is not always the best option. A big refactor can take forever; it’s like a chain reaction. You start with a few files or lines of code, which then scales so quickly that you’re suddenly in a situation where you’ve already refactored hundreds of files with no end in sight.

A better option is to do small refactors on the go. Refactor the code you’re touching based on the features you’re working on.

The approach that I like to follow in this case is one of the SOLID principles, Open-Closed principle, which suggests that a class should be open for extension and closed for modifications. If you can’t extend an existing class or file, then create a new one following this principle, and use it only when it’s required. Avoid changing existing implementations since it can scale quickly, and you might get lost in the refactoring instead of focusing on delivering the feature.


Dealing with legacy code shouldn’t be that painful. It depends on your approach to working with it.

Here are the things that you should do before starting the feature development:

  • Read the existing codebase.
  • Analyze the current backlog.
  • Add tests until the point you feel confident enough.
  • Set clear expectations to your client.

Once you’ve already started the development process, these are the things you should bear in mind:

  • Avoid major refactors; instead, do refactor on the go.
  • Add tests to any single feature or bug-fix you work on.

Let me know your thoughts in the comments section. If you have any other suggestions about how to deal with legacy code, feel free to share it with us.


0 5 Continue Reading →

Developer levels: the right skill set for the job.

Back when software was developed in Fortran and C, you needed a lot of knowledge to write anything of significance.  Originally, Fortran lacked even the concept of a data structure [1].  In the 1990s, an array was a contiguous chunk of memory containing a fixed number of structs or of pointers. Alternatively, one could create a struct where one field was a pointer to the next struct in the array, a true linked list.  You had to write all the code that manipulated anything.  You had to decide if an array or a linked list was best for each situation.  You had to decide if you were gonna use Quick Sort or needed a Heap Sort or if a Bubble Sort was more than enough.

Additionally, there have always been design patterns and the insight to know when to use one over another; the need for an understanding of programming languages and their compilers which affect everything we do; as well as the operating systems on which everything is built.  This list is long, going down deep all the way to discrete applied mathematics and probability.  There is a lot one can know which affects the quality of the software we write.

Today, everything has changed.  Languages do more and more.  Frameworks are getting better and better.  With Ruby on Rails, inexpert coders have so much functionality built into Ruby and even more built into Rails.  Given the objects which contain data structure and an astonishing amount of algorithms and code doing so much of what you need. The ORM with migrations, algorithms and code doing almost all the database management you need, and generators which create boilerplate code inside an opinionated MVC layout, one can write a pretty complete web application while writing surprisingly little of the actual code.  It can be quite some time before one really must make a deep technical decision which one used to make from day one.

This has changed the nature of writing software.  Back then, no company would hire someone after nine months of training let alone nine weeks … but that happens now and reasonably so.  It is perhaps analogous to the difference between a mechanic who can work with a car and a mechanical engineer who can design a car.  An upshot of this is the question of how do we categorize people writing software. When asked, I figure software people, particularly those who write applications, generally fall into about 3 categories.  This post is in no way scientific. It is written in a definitive voice but understand these are generalizations. This is just for the sake of starting a discussion and being analytical.  I have no proof.  Your mileage may vary.


Coders know how to … code.  They may no longer be muggles but they are more Ron Weasley than Hermione Granger.  They might know a few incantations but there’s still a lot of smoke.  They often use examples or starter apps.  When hitting a roadblock, which normally comes with an error message, they will put that error message into a search engine and see what comes up on StackOverflow.  They find a solution that sounds good and try it.  If that one fails, they try another. Eventually one works.  They can’t really own their code because so much of it is still magic to them. But, they can write serviceable code that works the way it should work.  Their knowledge is usually narrow, shallow and limited [2].  It should be said most are voracious and learning quickly about all the stuff they don’t know.  They do well in a collaborative team environment especially when they get to pair.  Many will go on to be solid developers.



Developers have a much broader understanding than Coders of the frameworks they use and languages in which they are written.  They understand their code.  When it breaks, they generally know why and can often fix it.  They understand objects; how to write a good one and, preferably, how to test it well.  They understand where the magic lies and often how it works.  They have an understanding of the underlying technologies (SQL, HTTP, SSH, Unix, etc.) and how to work with them directly.  As they become more senior they will know more about more technologies and understand how and when to use them.  Their knowledge is still clearly limited.  They might know a lot about one area, technology or layer and know little or nothing about others. They do not have the knowledge and experience to architect complex systems well but can build well thought-out features that cut across much of an application and know how to refactor properly to bring simplicity and elegance to a complicated design.



Engineers have deep knowledge of most every layer of the system on which they work from the OS and servers on which things run, the compiler that munches their code, through to the languages they use and the frameworks on which their products are built.  They understand patterns and architectures, can determine which is best at this moment and can explain why.  They know where the magic lies and understand how it is implemented and how to extend or fix that magic.  Whereas they often have a degree in computer science, there is a growing number who do not, who have delved in and taught themselves.  They understand their code as well as the underlying technologies and they also understand the theories behind why things should or should not work a particular way.  This gives them the facility to fully understand and design architectures as well as solid objects and well-thought-out tests.




When building a team to build your applications, you must know what mix of skills you need and who can provide those in the same way Ford or Tesla will have a mix of skills on a team creating a new car, some deep engineering skills, some mechanic skills.  There are many senior engineers who can architect and understand objects but have fewer skills at coding than some coders.  Many ambitious coders know the mechanics of a specific technology and can, especially with oversight, use that technology more effectively than others with more overall experience and knowledge.  Personally, I have found pairing two such people (one with more specific tech knowledge and one with more in-depth knowledge) can be very powerful.  They can learn from each other and your team gets stronger faster.

We must understand who is who, what to expect from each, how to help each grow to their potential and how to get the best code our team can build.  These are complicated enough that each should be another post in what I expect will become a series.

It is a brave new world in which we build applications. There are amazing advances in technology that allow us to build a better product faster than we could ever build in the past.  It has created the opportunity for many more to be able to contribute in meaningful ways.

Thanks for reading!

This is the first of a series of guest posts by Ken Decanio, a software engineer, architect and product manager.  If you would like to read more of his work, you can find find it at his blog.



[1] Ask me about the DD Array someday.

[2] Actually, it is preferable that a Coder’s knowledge be narrow and focused but that’s another post.



Photo credits:

2 6 Continue Reading →