DEV Community

Cover image for Code Smell 109 - Automatic Properties
Maxi Contieri
Maxi Contieri

Posted on • Updated on • Originally published at maximilianocontieri.com

Code Smell 109 - Automatic Properties

What happens if you combine 4 code smells?

TL;DR: Avoid Getters, Avoid Setters, Avoid Metaprogramming. Think about Behavior.

Problems

Solutions

  1. Remove automatic setters and getters

Context

Setters and getters are a bad industry practice.

Many IDEs favor this code smell.

Some languages provide explicit support to build anemic models and DTOs.

Sample Code

Wrong

class Person
{
  public string name 
  { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Right

class Person
{
  private string name  

  public Person(string personName)
  {
    name = personName;
    //imutable
    //no getters, no setters
  }

  //... more protocol, probably accessing private variable name
}
Enter fullscreen mode Exit fullscreen mode

Detection

[X] Automatic

This is a language feature.

We should avoid immature languages or forbid their worst practices.

Tags

  • Encapsulation

Conclusion

We need to think carefully before exposing our properties.

The first step is to stop thinking about properties and focus solely on behavior.

Relations

More Info

Credits

Photo by Kony on Unsplash


Nothing is harder than working under a tight deadline and still taking the time to clean up as you go.

Kent Beck


This article is part of the CodeSmell Series.

Discussion (6)

Collapse
jayjeckel profile image
Jay Jeckel

What use is that Person class when you can't even get the name from an instance?

Collapse
mcsee profile image
Maxi Contieri Author

Use = Behavior (Essential)
Name = Data (Accidental)

we are talking about objects and responsabilities, not anemic structs

Collapse
jayjeckel profile image
Jay Jeckel

You took usable but smelly code and turned it into code that does nothing and is useful for nothing.

The correct way to fix the smell of the original example would be the following. Immutability is enforced, but the name string isn't lost inside a worthless black box of a class.

public class Person
{
    public Person(string personName)
    {
        this.Name = personName;
    }

    public string Name { get; }
}
Enter fullscreen mode Exit fullscreen mode

Even better, with the latest version of .NET, the class should be declared as a record and the Name property should be declared get and init. Maybe you should stick to javascript or php or whatever for your smells, because your knowledge of proper C# seems distinctly lacking.

Thread Thread
mcsee profile image
Maxi Contieri Author

Hi

Thank you for advice
Your "correct" solutions has a getter which is another code smell, IMHO

So. I will stick to mine until I find a better one (without getters)

And records are yet another code smell

I think the problem is you care too much on the (accidental) data. I chose to care on (essential) behavior

But it is just my opinion

Thread Thread
jayjeckel profile image
Jay Jeckel

No, I care about behavior. The point is that a class with only private variables doesn't support any behavior.

Your "correct" solutions has a getter which is another code smell, IMHO

You're welcome to your opinion, but I categorically disagree with it. The smell would be having an object that doesn't allow you to retrieve data you put into it.

And records are yet another code smell

I'm not sure how to respond to that. Using a language feature that standardizes a way to enforce immutability and the handling of immutable objects is not a smell.

Thread Thread
mcsee profile image
Maxi Contieri Author

I think the problem is that Person protocol is incomplete. I will change that to clarify.
More behavior, no getters

I don't think they should be different kind of objects. Those with behavior and those for data transportation.

I honor the bijection. One Person in real world one person class