Reader small image

You're reading from  Refactoring with C#

Product typeBook
Published inNov 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781835089989
Edition1st Edition
Languages
Right arrow
Author (1)
Matt Eland
Matt Eland
author image
Matt Eland

Matt Eland is a Microsoft MVP in Artificial Intelligence (AI) who has been working with .NET since 2001. Matt has served as a senior engineer, software engineering manager, and .NET programming instructor. He is currently an AI specialist and senior consultant at Leading EDJE near Columbus, Ohio, where he helps companies with their software engineering and data science needs using C# and related technologies. Matt speaks and writes in his community and co-organizes the Central Ohio .NET Developers Group while pursuing a master's degree in data analytics.
Read more about Matt Eland

Right arrow

Agile Refactoring

In this final chapter, we’ll talk about refactoring as part of an agile team, succeeding with larger refactoring efforts, recovering when things go wrong, and incorporating deployment strategies to help make sure they don’t go wrong again.

It’s possible to win many small refactoring battles with small pieces of offending code but lose the overall “war” when you can’t address large-scale design issues. This chapter explores how to continue to fight and win the smaller refactoring battles with your code from sprint to sprint. We will also cover the larger strategic battle of making sure your application has the right design – and correct it to something better when it doesn’t.

This chapter covers the following topics:

  • Refactoring in an agile environment
  • Succeeding with agile refactoring strategies
  • Accomplishing large-scale refactorings
  • Recovering when refactoring goes wrong
  • Deploying...

Refactoring in an agile environment

Almost all development teams I work with use some form of agile software development to manage work over time in the form of short sprints, including any refactoring work.

In this section, we’ll cover the basics of agile workflows and how refactoring can fit into this type of environment. This is important because if refactoring work can’t fit into an agile workflow, refactoring simply won’t happen.

Key elements of agile teams

Agile software development was officially codified in the Manifesto for Agile Software Development (commonly called the Agile Manifesto) and flows from the following core preferences:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

Following these guiding principles, the exact “flavor” of agile differs from team...

Succeeding with agile refactoring strategies

Ongoing refactoring is important in an agile environment, so let’s talk about some ways of making sure code gets refactored regularly.

Dedicated work items for refactoring efforts

Remember that every line of code you and your team write should deliver business value, including your refactoring efforts.

Refactoring focuses on delivering value to the business by addressing known areas of technical risk and improving the speed the team can achieve in the future on related work in the targeted area.

Given these facts, it makes sense that refactoring efforts should be represented inside a sprint as user stories. Just as one developer might get a user story about integrating with a new external system for a partner, another developer might get a user story to refactor and establish additional tests around the data access layer.

In Chapter 15, we discussed tracking technical debt in a risk register. I didn’t make it...

Accomplishing large-scale refactorings

In my experience, successfully performing large-scale refactorings is one of the hardest challenges in all of software engineering.

I define large-scale refactoring as something on the scale of replacing an application or a major architectural layer of an application. Moving an application from one database technology to another, replacing a REST API with a gRPC API, upgrading from Web Forms to Blazor, or replacing your entire service layer are all examples of this.

Why large refactorings are difficult

These projects are challenging because they typically take longer than a single sprint to accomplish and must meet feature parity with software that has been developed over the years.

Additionally, software engineering projects are notoriously hard to accurately estimate, which is one of the reasons developers prefer agile software development over more traditional project management methodologies such as waterfall. Delays in software...

Recovering when refactoring goes wrong

Sometimes, despite your best efforts, refactoring efforts will fail. It may be due to gaps in your tests or mistaken assumptions about new technologies, but a certain percentage of your refactoring attempts will fail.

The impact of failed refactorings

Failed refactorings can be both frustrating and a serious challenge to future refactoring work. After all, a significant barrier to refactoring is the belief that legacy code is so brittle that touching it will break it. When you change code and it breaks, you make it harder to change code in the future.

When refactoring fails, you sometimes get to make a quick patch to address the issue you introduced. In this case, the code is refactored and service gets restored, but you’ve lost some of the team’s trust.

Other times, failures in refactoring result in code getting rolled back to the previous version before you refactored it. Sometimes, you’ll get to make changes...

Deploying large-scale refactorings

Let’s talk about some ways of deploying code that can help you catch any issues that slip through before they become major problems.

Using feature flags

Feature flags are configuration settings that control whether features are active.

When you push out new code that includes a new capability, that code doesn’t have to be immediately available. You can deploy as usual with the new feature area disabled in the configuration.

Once you’re confident the rest of the software is working as intended, you can enable the new feature. If the feature winds up having issues, you can quickly disable it by flipping the feature flag back to its inactive state.

While feature flags are helpful when you’re releasing actual features, you can also use them with major refactoring efforts. For example, a feature flag might govern whether the system uses LegacyBookingSystem or RevisedBookingSystem.

Tip

Feature flag libraries...

Case study – Cloudy Skies Airlines

As we close this book, let’s take a final look at our case study company: Cloudy Skies Airlines.

Cloudy Skies started with unmaintainable systems they were afraid to touch for fear of introducing critical bugs. They carried out a systematic review of the technical debt in their codebase and the quality issues the team had encountered in the past year.

As a result, the team was able to prioritize a list of key areas of technical debt and identify critical areas lacking unit tests. Cloudy Skies carried out several refactoring sprints to address the most critical areas first, putting a heavy emphasis on expanding their unit tests.

Once the quality hotspots were largely addressed, Cloudy Skies went back to a standard agile development cadence but allocated about 30% of their work each sprint toward paying down technical debt.

Many of the systems Cloudy Skies used were out of date, but Cloudy Skies was able to use .NET Upgrade...

Summary

In this chapter, we explored the unique challenges of refactoring in an agile environment and strategies for including refactoring work inside agile sprints.

We also looked at ways of accomplishing large-scale refactorings and how to respond when things don’t go as planned.

This chapter also touched on some deployment and automation processes that can reduce the impact of issues on end users and minimize the risk of human error through feature flags, blue/green deployments, and CI/CD practices.

Toward more sustainable software

This book took you on a journey from the nature of technical debt to the procedures of refactoring. We talked about how to safely test and structure your software and how to evaluate code for best practices, prioritize, and communicate technical debt.

We also talked about how the C# language and features of Visual Studio support you in this journey toward more sustainable software development.

Every year our world changes a little as Microsoft unveils new C# preview features at the beginning of the year and releases them near the end.

These capabilities give us a wide range of capabilities to tackle the development problems of today and tomorrow, but the reality is that software development continues to change.

Software and software development grows more complex each year. Meanwhile, many teams are stuck maintaining yesterday’s code.

It doesn’t have to be this way. You can modernize your software, and you can do it in an...

Questions

  1. How can technical debt be paid down inside of an agile setting?
  2. Why are large rewrites hard? What processes can help with this?
  3. What variances do you see right now in how you deploy and test software?

Further reading

You can find more information about the materials from this chapter at these URLs:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Refactoring with C#
Published in: Nov 2023Publisher: PacktISBN-13: 9781835089989
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Matt Eland

Matt Eland is a Microsoft MVP in Artificial Intelligence (AI) who has been working with .NET since 2001. Matt has served as a senior engineer, software engineering manager, and .NET programming instructor. He is currently an AI specialist and senior consultant at Leading EDJE near Columbus, Ohio, where he helps companies with their software engineering and data science needs using C# and related technologies. Matt speaks and writes in his community and co-organizes the Central Ohio .NET Developers Group while pursuing a master's degree in data analytics.
Read more about Matt Eland