Techno Blender
Digitally Yours.

Refactoring: Make this code readable | by Betty LD | Nov, 2022

0 42


“When programming, always follow the camping rule: Always leave the code base healthier than when you found it.” Martin Fowler [2].

This article is written for developers, tech leaders, or curious people that want to understand how to save time on a given codebase, how to make the development process faster and how to make the developers feel better, and empower them to maintain a healthy and agile codebase. Refactoring is an embedded activity in software engineering which requires skills and experience. I’ve written this article as a brief summary of my own experience, supported by the great books Refactoring [2], and Clean Craftmanship [1].

I’ve laid out why refactoring is absolutely essential and should be part of all development activities, and listed the many order of benefits it provides. Then I’ve explained what is the goal to achieve when refactoring and finally what and how to refactor common patterns.

Photo by andersjilden from Unsplash

Refactoring aims to improve the code design. A good design avoids managing rigid, inflexible, and fragile codebase. When the code base is so impracticable that testing and refactoring are slow and avoided. This is dying software. Developers will always need to implement new features in the code. The cost of change should not be more than the expected scope of that change.

A good design follows four rules [1]:

  1. No regression, tests pass
  2. Reveal intent (code expressiveness)
  3. No duplication
  4. Small (fewest possible classes, fewest possible method).

Tests:

A good design has good test coverage. What is the relationship between code design and code coverage? The reason is that testable code is decoupled code. The code being tested must be designed to be tested. In the TDD framework, writing code comes before writing tests.

A good test coverage also helps to improve the design with time.

Revealing intent:

The code should be self-explanatory. Every comment that expresses “what” the code does should be replaced by a more expressive code. We only keep commenting on the “why” of the code. The name of the variable, function, and type are deeply descriptive. Consider writing code like writing a story. First, the character should be described before their story start. Then, the story should be clear to the reader, directly linked to the already-defined characters, and finally, the story should be logically articulated. If the name of a variable or a method is unclear, one has to waste time when reading it.

The only thing that the author does not have in the story is why he chose to write the story as he does. This is where we accept the use of comments.

The tests give the context of the code and the intention behind it. This is why taken together, the code and tests are an expression of what each element of the system is, what the system does, and how the system is used.

Small:

YAGNI framework: “What if you aren’t gonna need it”

Good code also frees your time. If the code meaning is obfuscated, all the future code users will ask you questions, will misunderstand the meaning of your functions, and waste their and your time to grasp the functionalities. Save your future self and other people time to write it correctly the first time.

Also, if you are not available, the team should still be able to reuse your work and move the project forward.

With this in mind, now we can start refactoring.

You need a goal to refactor as the direction to focus on before starting refactoring.

Why we should refactor?

  • Some projects require experimental code with quick and dirty implementation. After proving that the code works, the code needs to be structured to be maintainable and extensible in the future.
  • The requirements have changed or our understanding of the problem has evolved and the existing code design does not meet our needs anymore. Refactoring improves the code design at any stage of the software development process.
  • Refactoring improves code readability. When writing code, there are two steps: make the code work and then make the code readable. It needs a lot of experience and skill to make these two at the same time. For me, I am sure it will be two distinct phases. After making the code functionally works (the code hits the acceptance criteria and shows the expected behavior), I need to make sure the future reader of the code will not spend the time I’ve already spent understanding the code behavior. The computer understands dirty code, humans don’t.
  • Refactoring helps to find bugs. When the code exists and works, most of us don’t spend time reading it deeply. Refactoring is an occasion to read attentively the code again and remember the assumption done when the code was once written.
  • Refactoring allows easy profiling to find performance bottlenecks later. Refactoring allows for future optimization of the function such as they can solve the current needs beautifully. It will be easier to find the bottleneck of a code and optimize it if the code is well-structured and clear.
  • A refactored code allows faster iteration. When the codebase is clear and its components well understood, it is easy to add new features. If the codebase grows without control into a monster of branches and lines, the development speed will be damaged. It will take time for the developer to remember how the code works every time. Besides clean code and good documentation, refactoring is about understanding once the code and putting back this knowledge into the code.
  • Refactored code allows for saving time and lines of code. Adding features does not mean adding code, but rather changing the existing code to include this new behavior. It should especially obvious when you do something similar to a part of the existing code. Every developer in a team should push for more refactoring rather than too little. It makes the code base healthier and the development faster. Refactoring is not slowing down the process, it’s making it faster overall. This brings an indisputable economic gain for the company that all leaders should seek. Regarding saving time, refactoring can be a rabbit hole so this activity needs to be timeboxed and scoped.
  • Refactored code allows better modularity (the ability to make modifications to a program while only having to understand a small part of it). To get this modularity, I need to ensure that related software elements are grouped together and the links between them are easy to find and understand.

Reducing how much modules need to know about each other helps reduce how much I need to put into my brain when I change something — and my brain isn’t as big as it used to be (that doesn’t say anything about the size of its container, though). [2]

When should we refactor?

Always actually.

  • before starting coding
  • during the coding
  • after the coding

The best time to refactor is just before I add a new feature to the codebase [2]. It gives me the time to see if we can’t just improve the code structure. If a parameter is hardcoded in the function, I’d rather put the parameter as an argument rather than copy/paste the function with a different hardcoded parameter. Refactoring before starting coding should come naturally. Since we need to read the codebase in order to understand what it does before we start working on it. When reading the code, if I see some small and minimal improvements to help the next reader (breaking down functions, adding documentation, etc), I should implement them before I start my work. Once the code is cleaned, we can see through it more clearly. Refactoring is not about helping the future user but also the current one.

Refactoring during coding is very natural as well. As we make the feature work, we need to make it readable iteratively.

Finally, before pushing a new pull request, we should make sure our code is cleaned, and formatted. While formatting is currently automatic in modern code editors like VSCode, the variable naming is still up to the developer. The variable name should be easy to understand and the code should be like a tale story for its user. Where each variable is introduced and where the story is logical and barely surprises the reader.

Especially nowadays, there is a lot of code of variable quality in the same codebase, and refactoring helps to improve the codebase altogether.

When you should NOT refactor:

  • Most of the time there is no need to refactor for generalization in the prevision of future needs (remember the YAGNI concept: “You Aren’t Going to Need It”).

Refactoring implicitly requires that you have a better knowledge of the current problem that you need to solve that the person that wrote the code before you.

Tests have many purposes too. It prevents bugs by ensuring the class is behaving as expected, and it helps the reader understand what the code is and is not supposed to do (don’t forget to test your exception and edge cases). Finally, the tests are necessary for a healthy refactoring process. When refactoring, we are looking for changing the code structure while keeping the same behavior. A test should follow three phases: setup, exercise, verify [2].

Before refactoring, we need to make sure that the tests exist and that tests pass. The tests should run fast, under one minute. Then you can make the famous cyclic repetition:

  • Refactor
  • Run the tests
  • Commit changes

Almost as often you make a change, otherwise, the moment one test is broken, it will be difficult to know which change modified the behavior of the code.

So this refactoring loop “refactor, test, commit” should be done on very small code chunks. We all make mistakes and we’ll probably let a bug slip in. We want to catch easily the bug if a test fails after changing 500 lines of code, I will have a hard time finding where the bug is.

I like how Brett Slatkin put the pre-requisites for refactoring:

  • fast tests
  • source controls
  • willing to make mistakes

We’ve seen that there are many potential reasons for refactoring. Nevertheless, programmers have more than fewer things to do and can’t devote him/herself to unnecessary activities. Then we need to be very sensible about the right signal for refactoring. In this section, I will describe my favorite refactoring signals. The signals that I need to refactor and make some changes. The changes will always follow three majors stages:

  • try to understand what’s going on
  • move the insights back into the code
  • continue to understand and add boundaries in a beneficial positive loop.

Now let’s dive into it.

Refactoring scope: When to start and when to stop

When you have to read the code but the story of the code is unclear. The function, modules, and variables do not have are not good names and can’t clearly communicate what they are supposed to do.

When there is code reused in different parts, we extract a function from it and call this function instead.

Decompose the long function into smaller functions. You can use the space, commented paragraph, or loops to break it down easily.

When a class becomes too big, you can try extracting another class. Take variables that go together, and that share suffixes or prefixes. The relationship of this extracted class with the originally large class could be inheritance or composition. Try eliminating potential redundancy as well.

This is possible to avoid by using classes or dataclasses objects as arguments. We then replace the parameter with a query. For example, if multiple functions use the variables “start_date” and “end_date” together as arguments. You may use the variable “date_range” instead. Grouping the data into a new structure make the relationship between the parameter more explicit.

  • Divergent change and shotgun surgery [2]

What Martin Fowler calls “Divergent change” in his book “Refactoring”, happens when one module is often changed in different ways for different reasons. Most of the time, the part in the code prone to change should be separated and then, we can avoid changing a module for its interfacing. It can be loading the data into one module and processing the data in another module.

The “Shotgun surgery” is the opposite pattern, when one change requires a lot of small edits in many different classes. In that case, unifying the small edit into one function or finding a common pattern to extract and call can be useful to reduce the edit time.

For specific usage, it’s clearer to use an object that encapsulates the domain-specific (temperature, coordinate system, money) logic than primitive types.

  • The long list of “if” statement

A long list of conditions may be replaced by polymorphism. The condition can be encapsulated in different classes that have a shared method (inherited from an abstract class for example). Instead of calling a series of if, we can call the instance that is from a family of classes sharing the same parent class (and then abstract method).

This was one of the most counter-intuitive refactorings advice I received. Refactoring a loop into successive pipeline stages. Loops that have multiple responsibilities can be confusing. They could be refactored using built-in “filter”, “map”, “reduce” (see examples at this link), or line list comprehension. This allows breaking down a loop into multiple loops (optimization of performance can be dealt with after making the code clear if necessary) that are more readable and easier to debug.

  • Removing unnecessary complexity

It can be merging two classes that became common. It can often happen that an abstract class is not necessary anymore (only one child class). Removing a class that tries to be too generic while it’s not currently needed. You can also remove unused (dead) code from the codebase.

One function should carry one responsibility. When the code tries to do two (or more!) different things, we should try splitting it into different functions. The easier is to split the functions into two sequential phases. Then we can focus on understanding each function separately without having to understand the other functions around simultaneously.

This is also true for variables, if you use the same variables for different value holding, it is preferable to use two distinct variables instead. It occurs often with placeholder variables such as tmp , var , res, etc.

# Before
def transform_img(img, angle=90):
img = rgb_to_binary(img)
img = rotate_img(img, angle)
return img
# After
def transform_img(img, angle=90):
binary_img = rgb_to_binary(img)
rotated_binary_img = rotate_img(binary_img, angle)
return rotated_binary_img

Encapsulation means that modules need to know less about other parts of the system.

intersection_coordinates = road_edge.geo.coordinates

could be replaced with

intersection_coordinates = road_edge.coordinatesclass RoadEdge:
@property
def coordinates(self):
return self.geo.coordinates

This will facilitate any future changes in the class RoadEdge and reduce the number of edits in all the code. The client code does not need to know about the geo attribute of the class to call the coordinates.

We also use encapsulation to transform mutable records into objects:

# Before
image_sample = {"image": image_array, "dataset": "SatelliteDataset_01", "resolution": 0.5}
# After
@dataclass
def ImageSample:
image_array: np.ndarray
dataset: str
resolution: float
image_sample = ImageSample(image_array, "SatelliteDataset_01", 0.5)

When a function references elements from another context more than the one it currently resides in, it is a sign to move this function to the other context.

It can happen across class inheritance as well. If the subclass inherits a method they don’t need from their parent’s class, it means the methods can move down to the sibling class that is the only one to use this method.

You can also move statements such as the things that are related to each other to appear altogether. If several lines of code refer to the same elements they should appear one after each other in the code rather than intermingled with lines of code accessing other data structures. A common case for sliding statements is variable declaration and usage of the variable that should always be as close as possible.

If a family of classes uses the same interface, they can be substituted for each other.

Extracting a part of the code outside from a code block and renaming it. It can be:

  1. Extract variables
  2. Extract functions
  3. Using variables from functions
  4. Extract a class out of the code

Extract functions improve readability and class makes testing easy, because we can test the intermediate results by testing the function that produces them.

Extracting functions from a block of code can be subjective. Should I extract the code into multiple successive functions or let the logic flows in 50 successive lines of code? Some people say that the function should fit on a computer screen, and some say that only reused functions should be extracted otherwise let the code be inline. It also makes sense to extract functions when the code becomes unclear on what it is doing. A function is a chapter in the story of the code, the story should be clear and readable. It is similar for variables, we can break down complex calculations into intermediary variables. In the end, it’s up to you to decide what would be the clearest.

[1] Clean Craftmanship, Cecil Martin.

[2] Refactoring, Martin Fowler, Kent Beck.


“When programming, always follow the camping rule: Always leave the code base healthier than when you found it.” Martin Fowler [2].

This article is written for developers, tech leaders, or curious people that want to understand how to save time on a given codebase, how to make the development process faster and how to make the developers feel better, and empower them to maintain a healthy and agile codebase. Refactoring is an embedded activity in software engineering which requires skills and experience. I’ve written this article as a brief summary of my own experience, supported by the great books Refactoring [2], and Clean Craftmanship [1].

I’ve laid out why refactoring is absolutely essential and should be part of all development activities, and listed the many order of benefits it provides. Then I’ve explained what is the goal to achieve when refactoring and finally what and how to refactor common patterns.

Photo by andersjilden from Unsplash

Refactoring aims to improve the code design. A good design avoids managing rigid, inflexible, and fragile codebase. When the code base is so impracticable that testing and refactoring are slow and avoided. This is dying software. Developers will always need to implement new features in the code. The cost of change should not be more than the expected scope of that change.

A good design follows four rules [1]:

  1. No regression, tests pass
  2. Reveal intent (code expressiveness)
  3. No duplication
  4. Small (fewest possible classes, fewest possible method).

Tests:

A good design has good test coverage. What is the relationship between code design and code coverage? The reason is that testable code is decoupled code. The code being tested must be designed to be tested. In the TDD framework, writing code comes before writing tests.

A good test coverage also helps to improve the design with time.

Revealing intent:

The code should be self-explanatory. Every comment that expresses “what” the code does should be replaced by a more expressive code. We only keep commenting on the “why” of the code. The name of the variable, function, and type are deeply descriptive. Consider writing code like writing a story. First, the character should be described before their story start. Then, the story should be clear to the reader, directly linked to the already-defined characters, and finally, the story should be logically articulated. If the name of a variable or a method is unclear, one has to waste time when reading it.

The only thing that the author does not have in the story is why he chose to write the story as he does. This is where we accept the use of comments.

The tests give the context of the code and the intention behind it. This is why taken together, the code and tests are an expression of what each element of the system is, what the system does, and how the system is used.

Small:

YAGNI framework: “What if you aren’t gonna need it”

Good code also frees your time. If the code meaning is obfuscated, all the future code users will ask you questions, will misunderstand the meaning of your functions, and waste their and your time to grasp the functionalities. Save your future self and other people time to write it correctly the first time.

Also, if you are not available, the team should still be able to reuse your work and move the project forward.

With this in mind, now we can start refactoring.

You need a goal to refactor as the direction to focus on before starting refactoring.

Why we should refactor?

  • Some projects require experimental code with quick and dirty implementation. After proving that the code works, the code needs to be structured to be maintainable and extensible in the future.
  • The requirements have changed or our understanding of the problem has evolved and the existing code design does not meet our needs anymore. Refactoring improves the code design at any stage of the software development process.
  • Refactoring improves code readability. When writing code, there are two steps: make the code work and then make the code readable. It needs a lot of experience and skill to make these two at the same time. For me, I am sure it will be two distinct phases. After making the code functionally works (the code hits the acceptance criteria and shows the expected behavior), I need to make sure the future reader of the code will not spend the time I’ve already spent understanding the code behavior. The computer understands dirty code, humans don’t.
  • Refactoring helps to find bugs. When the code exists and works, most of us don’t spend time reading it deeply. Refactoring is an occasion to read attentively the code again and remember the assumption done when the code was once written.
  • Refactoring allows easy profiling to find performance bottlenecks later. Refactoring allows for future optimization of the function such as they can solve the current needs beautifully. It will be easier to find the bottleneck of a code and optimize it if the code is well-structured and clear.
  • A refactored code allows faster iteration. When the codebase is clear and its components well understood, it is easy to add new features. If the codebase grows without control into a monster of branches and lines, the development speed will be damaged. It will take time for the developer to remember how the code works every time. Besides clean code and good documentation, refactoring is about understanding once the code and putting back this knowledge into the code.
  • Refactored code allows for saving time and lines of code. Adding features does not mean adding code, but rather changing the existing code to include this new behavior. It should especially obvious when you do something similar to a part of the existing code. Every developer in a team should push for more refactoring rather than too little. It makes the code base healthier and the development faster. Refactoring is not slowing down the process, it’s making it faster overall. This brings an indisputable economic gain for the company that all leaders should seek. Regarding saving time, refactoring can be a rabbit hole so this activity needs to be timeboxed and scoped.
  • Refactored code allows better modularity (the ability to make modifications to a program while only having to understand a small part of it). To get this modularity, I need to ensure that related software elements are grouped together and the links between them are easy to find and understand.

Reducing how much modules need to know about each other helps reduce how much I need to put into my brain when I change something — and my brain isn’t as big as it used to be (that doesn’t say anything about the size of its container, though). [2]

When should we refactor?

Always actually.

  • before starting coding
  • during the coding
  • after the coding

The best time to refactor is just before I add a new feature to the codebase [2]. It gives me the time to see if we can’t just improve the code structure. If a parameter is hardcoded in the function, I’d rather put the parameter as an argument rather than copy/paste the function with a different hardcoded parameter. Refactoring before starting coding should come naturally. Since we need to read the codebase in order to understand what it does before we start working on it. When reading the code, if I see some small and minimal improvements to help the next reader (breaking down functions, adding documentation, etc), I should implement them before I start my work. Once the code is cleaned, we can see through it more clearly. Refactoring is not about helping the future user but also the current one.

Refactoring during coding is very natural as well. As we make the feature work, we need to make it readable iteratively.

Finally, before pushing a new pull request, we should make sure our code is cleaned, and formatted. While formatting is currently automatic in modern code editors like VSCode, the variable naming is still up to the developer. The variable name should be easy to understand and the code should be like a tale story for its user. Where each variable is introduced and where the story is logical and barely surprises the reader.

Especially nowadays, there is a lot of code of variable quality in the same codebase, and refactoring helps to improve the codebase altogether.

When you should NOT refactor:

  • Most of the time there is no need to refactor for generalization in the prevision of future needs (remember the YAGNI concept: “You Aren’t Going to Need It”).

Refactoring implicitly requires that you have a better knowledge of the current problem that you need to solve that the person that wrote the code before you.

Tests have many purposes too. It prevents bugs by ensuring the class is behaving as expected, and it helps the reader understand what the code is and is not supposed to do (don’t forget to test your exception and edge cases). Finally, the tests are necessary for a healthy refactoring process. When refactoring, we are looking for changing the code structure while keeping the same behavior. A test should follow three phases: setup, exercise, verify [2].

Before refactoring, we need to make sure that the tests exist and that tests pass. The tests should run fast, under one minute. Then you can make the famous cyclic repetition:

  • Refactor
  • Run the tests
  • Commit changes

Almost as often you make a change, otherwise, the moment one test is broken, it will be difficult to know which change modified the behavior of the code.

So this refactoring loop “refactor, test, commit” should be done on very small code chunks. We all make mistakes and we’ll probably let a bug slip in. We want to catch easily the bug if a test fails after changing 500 lines of code, I will have a hard time finding where the bug is.

I like how Brett Slatkin put the pre-requisites for refactoring:

  • fast tests
  • source controls
  • willing to make mistakes

We’ve seen that there are many potential reasons for refactoring. Nevertheless, programmers have more than fewer things to do and can’t devote him/herself to unnecessary activities. Then we need to be very sensible about the right signal for refactoring. In this section, I will describe my favorite refactoring signals. The signals that I need to refactor and make some changes. The changes will always follow three majors stages:

  • try to understand what’s going on
  • move the insights back into the code
  • continue to understand and add boundaries in a beneficial positive loop.

Now let’s dive into it.

Refactoring scope: When to start and when to stop

When you have to read the code but the story of the code is unclear. The function, modules, and variables do not have are not good names and can’t clearly communicate what they are supposed to do.

When there is code reused in different parts, we extract a function from it and call this function instead.

Decompose the long function into smaller functions. You can use the space, commented paragraph, or loops to break it down easily.

When a class becomes too big, you can try extracting another class. Take variables that go together, and that share suffixes or prefixes. The relationship of this extracted class with the originally large class could be inheritance or composition. Try eliminating potential redundancy as well.

This is possible to avoid by using classes or dataclasses objects as arguments. We then replace the parameter with a query. For example, if multiple functions use the variables “start_date” and “end_date” together as arguments. You may use the variable “date_range” instead. Grouping the data into a new structure make the relationship between the parameter more explicit.

  • Divergent change and shotgun surgery [2]

What Martin Fowler calls “Divergent change” in his book “Refactoring”, happens when one module is often changed in different ways for different reasons. Most of the time, the part in the code prone to change should be separated and then, we can avoid changing a module for its interfacing. It can be loading the data into one module and processing the data in another module.

The “Shotgun surgery” is the opposite pattern, when one change requires a lot of small edits in many different classes. In that case, unifying the small edit into one function or finding a common pattern to extract and call can be useful to reduce the edit time.

For specific usage, it’s clearer to use an object that encapsulates the domain-specific (temperature, coordinate system, money) logic than primitive types.

  • The long list of “if” statement

A long list of conditions may be replaced by polymorphism. The condition can be encapsulated in different classes that have a shared method (inherited from an abstract class for example). Instead of calling a series of if, we can call the instance that is from a family of classes sharing the same parent class (and then abstract method).

This was one of the most counter-intuitive refactorings advice I received. Refactoring a loop into successive pipeline stages. Loops that have multiple responsibilities can be confusing. They could be refactored using built-in “filter”, “map”, “reduce” (see examples at this link), or line list comprehension. This allows breaking down a loop into multiple loops (optimization of performance can be dealt with after making the code clear if necessary) that are more readable and easier to debug.

  • Removing unnecessary complexity

It can be merging two classes that became common. It can often happen that an abstract class is not necessary anymore (only one child class). Removing a class that tries to be too generic while it’s not currently needed. You can also remove unused (dead) code from the codebase.

One function should carry one responsibility. When the code tries to do two (or more!) different things, we should try splitting it into different functions. The easier is to split the functions into two sequential phases. Then we can focus on understanding each function separately without having to understand the other functions around simultaneously.

This is also true for variables, if you use the same variables for different value holding, it is preferable to use two distinct variables instead. It occurs often with placeholder variables such as tmp , var , res, etc.

# Before
def transform_img(img, angle=90):
img = rgb_to_binary(img)
img = rotate_img(img, angle)
return img
# After
def transform_img(img, angle=90):
binary_img = rgb_to_binary(img)
rotated_binary_img = rotate_img(binary_img, angle)
return rotated_binary_img

Encapsulation means that modules need to know less about other parts of the system.

intersection_coordinates = road_edge.geo.coordinates

could be replaced with

intersection_coordinates = road_edge.coordinatesclass RoadEdge:
@property
def coordinates(self):
return self.geo.coordinates

This will facilitate any future changes in the class RoadEdge and reduce the number of edits in all the code. The client code does not need to know about the geo attribute of the class to call the coordinates.

We also use encapsulation to transform mutable records into objects:

# Before
image_sample = {"image": image_array, "dataset": "SatelliteDataset_01", "resolution": 0.5}
# After
@dataclass
def ImageSample:
image_array: np.ndarray
dataset: str
resolution: float
image_sample = ImageSample(image_array, "SatelliteDataset_01", 0.5)

When a function references elements from another context more than the one it currently resides in, it is a sign to move this function to the other context.

It can happen across class inheritance as well. If the subclass inherits a method they don’t need from their parent’s class, it means the methods can move down to the sibling class that is the only one to use this method.

You can also move statements such as the things that are related to each other to appear altogether. If several lines of code refer to the same elements they should appear one after each other in the code rather than intermingled with lines of code accessing other data structures. A common case for sliding statements is variable declaration and usage of the variable that should always be as close as possible.

If a family of classes uses the same interface, they can be substituted for each other.

Extracting a part of the code outside from a code block and renaming it. It can be:

  1. Extract variables
  2. Extract functions
  3. Using variables from functions
  4. Extract a class out of the code

Extract functions improve readability and class makes testing easy, because we can test the intermediate results by testing the function that produces them.

Extracting functions from a block of code can be subjective. Should I extract the code into multiple successive functions or let the logic flows in 50 successive lines of code? Some people say that the function should fit on a computer screen, and some say that only reused functions should be extracted otherwise let the code be inline. It also makes sense to extract functions when the code becomes unclear on what it is doing. A function is a chapter in the story of the code, the story should be clear and readable. It is similar for variables, we can break down complex calculations into intermediary variables. In the end, it’s up to you to decide what would be the clearest.

[1] Clean Craftmanship, Cecil Martin.

[2] Refactoring, Martin Fowler, Kent Beck.

FOLLOW US ON GOOGLE NEWS

Read original article here

Denial of responsibility! Techno Blender is an automatic aggregator of the all world’s media. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials, please contact us by email – [email protected]. The content will be deleted within 24 hours.
Leave a comment