## DEV Community π©βπ»π¨βπ» is a community of 968,547 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Maxi Contieri

Posted on • Originally published at maximilianocontieri.com

# Code Smell 89 - Math Feature Envy

One class calculating formulas for another class.

TL;DR: Leave the formulas to the objects gathering the information.

# Problems

• Declaratively

• Low reuse

• Real-world concept missing

• Encapsulation

# Solutions

1. Move the math formula to the class

2. Search for real-world abstractions

# Sample Code

## Wrong

``````function area(rectangle) {
return rectange.width * rectangle.height;
//Notice we are sending consecutive messages to
//the same object and doing calculations
}
``````

## Right

``````class Rectangle {
constructor(width, height, color) {
this.height = height;
this.width = width;
}

area() {
return this.width * this.height;
}
}
``````

# Detection

Since many cascading messages are sending to the same object, we can detect a pattern.

# Tags

• Encapsulation

• Coupling

# Conclusion

This is a very basic smell. If we are manipulating another object characteristics, we should let it do it the maths for us.

# Credits

Photo by Michal Matlon on Unsplash

Computer science is not about machines, in the same way that astronomy is not about telescopes. There is an essential unity of mathematics and computer science.

Michael R. Fellows

James Robb • Edited on

I suppose it depends on the implementation, for example:

``````function rectangularArea(rectangle) {
return rectangle.width * rectangle.height;
}
``````

This is perfectly fine code for me as it describes what the area is for.

Using a type system allows us to enforce this also:

``````type Rectangle = { width: number, height: number };

function rectangularArea(rectangle: Rectangle) {
return rectangle.width * rectangle.height;
}
``````

We could even enforce behavioral logic on the type if we really wanted to:

``````type Shape = { area: () => number };
type Rectangle = Shape & { width: number, height: number };

function rectangularArea(rectangle: Rectangle) {
return rectangle.area();
}
``````

Interested to hear your thoughts on this kind of direction though, is it too much or too little or causing other smells potentially?

Maxi Contieri • Edited on

You are using an external function, stripping object accidental properties and performing calculations outside of it. this violates reuse, information hiding principle, class cohesion and encapsulation.

The area is what the rectangle points out. not an external function.
You are confusing data (accidental) with behavior (essential)

James Robb

Can you give an example of each case you mentioned and a suitable resolution in your opinion?

What about in functional languages, how should this be approached there in your opinion?

Maxi Contieri

Hi again

Thanks for the comment.
I am not an expert on Functional Programming.
I'll stick to OOP, my area of knowledge.
Calculating the area of a shape (and how it does) it is shape's reposibility.
Example is on the article above.
Doing external manipulations is a code smell, according to my opinion

## π Friends don't let friends browse without dark mode.

Sorry, it's true.