SysAlchemy.Lab.Refactoring 0.1.0-alpha.18

This is a prerelease version of SysAlchemy.Lab.Refactoring.
dotnet add package SysAlchemy.Lab.Refactoring --version 0.1.0-alpha.18
NuGet\Install-Package SysAlchemy.Lab.Refactoring -Version 0.1.0-alpha.18
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SysAlchemy.Lab.Refactoring" Version="0.1.0-alpha.18" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SysAlchemy.Lab.Refactoring --version 0.1.0-alpha.18
#r "nuget: SysAlchemy.Lab.Refactoring, 0.1.0-alpha.18"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SysAlchemy.Lab.Refactoring as a Cake Addin
#addin nuget:?package=SysAlchemy.Lab.Refactoring&version=0.1.0-alpha.18&prerelease

// Install SysAlchemy.Lab.Refactoring as a Cake Tool
#tool nuget:?package=SysAlchemy.Lab.Refactoring&version=0.1.0-alpha.18&prerelease

SysAlchemy.Lab.Refactoring

This project is talking about all best practices on refactoring techniques.

Main references for this project is refactoring.guru website. The main difference is that you can learn refactoring in practice.

Refactoring is a systematic process of improving code without creating new functionality that can transform a mess into clean code and simple design

Dirty Code

Dirty code is result of inexperience multiplied by tight deadlines, mismanagement, and nasty shortcuts taken during the development process.

Clean Code

Clean code is code that is easy to read, understand and maintain. Clean code makes software development predictable and increases the quality of a resulting product.

Refactoring Process

Performing refactoring step-by-step and running tests after each change are key elements of refactoring that make it predictable and safe.

Code Smells

Code smells are indicators of problems that can be addressed during refactoring. Code smells are easy to spot and fix, but they may be just symptoms of a deeper problem with code.

Refactoring Techniques

Refactoring techniques describe actual refactoring steps. Most refactoring techniques have their pros and cons. Therefore, each refactoring should be properly motivated and applied with caution.

Clean code

The main purpose of refactoring is to fight technical debt. It transforms a mess into clean code and simple design.

Nice! But what’s clean code, anyway? Here are some of its features:

Clean code is obvious for other programmers.

And I’m not talking about super sophisticated algorithms. Poor variable naming, bloated classes and methods, magic numbers -you name it- all of that makes code sloppy and difficult to grasp.

Clean code does’t contain duplication.

Each time you have to make a change in a duplicate code, you have to remember to make the same change to every instance. This increases the cognitive load and slows down the progress.

Clean code contains a minimal number of classes and other moving parts.

Less code is less stuff to keep in your head. Less code is less maintenance. Less code is fewer bugs. Code is liability, keep it short and simple.

Clean code passes all tests.

You know your code is dirty when only 95% of your tests passed. You know you’re screwed when your test coverage is 0%.

Clean code is easier and cheaper to maintain!

Technical debt

Everyone does their best to write excellent code from scratch. There probably isn’t a programmer out there who intentionally writes unclean code to the detriment of the project. But at what point does clean code become unclean?

The metaphor of “technical debt” in regards to unclean code was originally suggested by Ward Cunningham.

If you get a loan from a bank, this allows you to make purchases faster. You pay extra for expediting the process - you don’t just pay off the principal, but also the additional interest on the loan. Needless to say, you can even rack up so much interest that the amount of interest exceeds your total income, making full repayment impossible.

The same thing can happen with code. You can temporarily speed up without writing tests for new features, but this will gradually slow your progress every day until you eventually pay off the debt by writing tests.

Causes of technical debt

Business pressure

Sometimes business circumstances might force you to roll out features before they’re completely finished. In this case, patches and kludges will appear in the code to hide the unfinished parts of the project.

Lack of understanding of the consequences of technical debt

Sometimes your employer might not understand that technical debt has “interest” insofar as it slows down the pace of development as debt accumulates. This can make it too difficult to dedicate the team’s time to refactoring because management does’t see the value of it.

Failing to combat the strict coherence of components

This is when the project resembles a monolith rather than the product of individual modules. In this case, any changes to one part of the project will affect others. Team development is made more difficult because it’s difficult to isolate the work of individual members.

Lack of tests

The lack of immediate feedback encourages quick, but risky workarounds or kludges. In worst cases, these changes are implemented and deployed right into the production without any prior testing. The consequences can be catastrophic. For example, an innocent-looking hotfix might send a weird test email to thousands of customers or even worse, flush or corrupt an entire database.

Lack of documentation

This slows down the introduction of new people to the project and can grind development to a halt if key people leave the project.

Lack of interaction between team members

If the knowledge base isn’t distributed throughout the company, people will end up working with an outdated understanding of processes and information about the project. This situation can be exacerbated when junior developers are incorrectly trained by their mentors.

Long-term simultaneous development in several branches

This can lead to the accumulation of technical debt, which is then increased when changes are merged. The more changes made in isolation, the greater the total technical debt.

Delayed refactoring

The project’s requirements are constantly changing and at some point it may become obvious that parts of the code are obsolete, have become cumbersome, and must be redesigned to meet new requirements.

On the other hand, the project’s programmers are writing new code every day that works with the obsolete parts. Therefore, the longer refactoring is delayed, the more dependent code will have to be reworked in the future.

Lack of compliance monitoring

This happens when everyone working on the project writes code as they see fit (i.e. the same way they wrote the last project).

Incompetence

This is when the developer just does’t know how to write decent code.

When to refactor

Rule of Three

  1. When you’re doing something for the first time, just get it done.
  2. When you’re doing something similar for the second time, cringe at having to repeat but do the same thing anyway.
  3. When you’re doing something for the third time, start refactoring.

When adding a feature

  • Refactoring helps you understand other people’s code. If you have to deal with someone else’s dirty code, try to refactor it first. Clean code is much easier to grasp. You will improve it not only for yourself but also for those who use it after you.
  • Refactoring makes it easier to add new features. It’s much easier to make changes in clean code.

When fixing a bug

Bugs in code behave just like those in real life: they live in the darkest, dirtiest places in the code. Clean your code and the errors will practically discover themselves.

Managers appreciate proactive refactoring as it eliminates the need for special refactoring tasks later. Happy bosses make happy programmers!

During a code review

The code review may be the last chance to tidy up the code before it becomes available to the public.

It’s best to perform such reviews in a pair with an author. This way you could fix simple problems quickly and gauge the time for fixing the more difficult ones.

How to refactor

Refactoring should be done as a series of small changes, each of which makes the existing code slightly better while still leaving the program in working order.

Checklist of refactoring done right way

The code should become cleaner.

If the code remains just as unclean after refactoring... well, I’m sorry, but you’ve just wasted an hour of your life. Try to figure out why this happened.

It frequently happens when you move away from refactoring with small changes and mix a whole bunch of refactorings into one big change. So it’s very easy to lose your mind, especially if you have a time limit.

But it can also happen when working with extremely sloppy code. Whatever you improve, the code as a whole remains a disaster.

In this case, it’s worthwhile to think about completely rewriting parts of the code. But before that, you should have written tests and set aside a good chunk of time. Otherwise, you’ll end up with the kinds of results we talked about in the first paragraph.

New functionality shouldn’t be created during refactoring.

Don’t mix refactoring and direct development of new features. Try to separate these processes at least within the confines of individual commits.

All existing tests must pass after refactoring.

There are two cases when tests can break down after refactoring:

  • You made an error during refactoring. This one is a no-brainer: go ahead and fix the error.
  • Your tests were too low-level. For example, you were testing private methods of classes.

In this case, the tests are to blame. You can either refactor the tests themselves or write an entirely new set of higher-level tests. A great way to avoid this kind of a situation is to write BDD-style tests.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0-alpha.18 51 3/17/2024
0.1.0-alpha.17 44 3/17/2024
0.1.0-alpha.16 54 3/17/2024