📜 ⬆️ ⬇️

Design smell: excessive attribute Required

This is the fourth post in the Poka-yoke design series - also known as encapsulation .

Recently, I read a post written with enthusiasm from a Microsoft technological event:
The [Required] attribute in the code automatically creates a record in the database that cannot accept null, and also creates a validation on the web page - simplicity [...]


I imagined that it might look something like this:
public class Smell { [Required] public int Id { get; set; } } 

Every time I see something like this, I get a little closer to death. If you have already read my previous post, now it should be painfully clear why this breaks the encapsulation. Despite the presence of the [Required] attribute, there is no guarantee that the Id property will ever be assigned a value . An attribute is simply a piece of garbage that proclaims something that cannot be returned.
This code is not fault tolerant.
I understand that the attribute mentioned in the tweet is intended to signal some tool (perhaps the Entity Framework) that the property should be displayed but the database schema does not accept null, but it is still superfluous. Attributes are the wrong way to declare an invariant statement.

Revised design
The [Required] attribute is redundant because there is a better way to declare that part of the data is necessary (required). This was possible since .NET 1.0. Here is the Poka-yoke version of the same declaration:
 public class Fragrance { private readonly int id; public Fragrance(int id) { this.id = id; } public int Id { get { return this.id; } } } 

This simple structural design shows that the field is really necessary (and if the ID field can only be a positive value, then you can add a protective expression). An instance of the Fragrance class can only be created with an ID. Since this is a structural design, this requirement is only strengthened, thanks to the compiler, which gives us quick feedback.
I understand that the [Required] attribute, mentioned earlier, is designed to solve problems with mapping objects into relational data, but instead of closing a hole for inconsistencies between objects and relational structures, it only expands it.
Instead of adding an extra redundant attribute, the team should force its toolkit to understand simple idioms for encapsulation, such as described above.
It is not so difficult to do. As an example, DI containers bloom on structural information encoded in constructors (this is called auto-connect ). The command can do this behind the scenes of the [Required] attribute. The [Required] attribute is a primitive and poisonous hack.
This is the main reason why I will never use the Entity Framework. It forces developers to break encapsulation - a principle that I refuse to compromise.
')
from the translator: forgot to publish the post as a translation. The original author is Mark Seemann. Link to the original.

Source: https://habr.com/ru/post/205098/


All Articles