Implementation of generic CRUD

Asked

Viewed 1,060 times

0

I have the following class CRUD that is generic:

public abstract class CRUD
{
    protected string tabela = null;
    protected object classe = null;

    public CRUD() {}

    public virtual void insert() { //código }
    public virtual void select() { //código }
}

I created another class whether it inherits from the class CRUD:

public abstract class PessoaCRUD : CRUD
{
   public PessoaCRUD()
   {
       tabela = "TBUsuarios";
       classe = this;    
   }

   //sobrescrita do metódo da classe pai
   public void insert() { //código }
}

And I have my class Person who inherits from Pessoacrud:

public class Pessoa : PessoaCRUD
{
    public string Nome { get; set; }
    public int Idade { get; set; }
}

And when I need to use the class person will be something like this:

Pessoa pessoa = new Pessoa();

pessoa.Nome = "Julia";
pessoa.Idade = 23;
pessoa.Insert();

At first it’s working, but I was in doubt, I could do the class Pessoa inherits from the class CRUD, but if any method needed superscript it would have to be implemented in the class Pessoa, and not wanting to pollute the class Pessoa with methods related to CRUD created the class PessoaCRUD.

Is it correct to implement so? otherwise what would be a better approach, taking into account design standards?

3 answers

4


It’s right to implement like this?

No. The approach is incorrect for collection manipulation as it makes the record manipulation procedure complex and poor in performance.

You are defining a class that stores data and at the same time manages itself. Pro case of 1000 records, for example, you would have to call insert 1000 times, one for each object. The biggest problem is spending on memory, replicating 1000 times objects with the same business logic.

Otherwise what would be a better approach, taking into account design standards?

This is the classic case of implementing a repository, but there are some observations to be made.

1. Separate the data class from the record manipulation class.

The class CRUD is correct from a repository’s point of view, except for the property classe, which is neither useful nor necessary for its implementation.

What is interesting to do is to use generic type to separate the data representation class from the class that does the database operations (aka repository):

public abstract class CRUD<T>
    where T: IEntidade
{
    protected string tabela = null;
    protected object classe = null;

    public CRUD() {}

    public virtual void insert(T objeto) { //código }
    public virtual void select(int id) { //código }
    ...
}

2. Use generic classes to define your repository

Already PessoaCRUD doesn’t have to be abstract:

public class PessoaCRUD<Pessoa> : CRUD<Pessoa>
{
   public PessoaCRUD()
   {
       tabela = "TBUsuarios";
   }

   //sobrescrita do metódo da classe pai
   public override void insert(Pessoa objeto) { //código }
}

Pessoa should only represent data:

public class Pessoa : IEntidade
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public int Idade { get; set; }
}

3. Restrict your data classes by interfaces

Finally, define the interface IEntidade to define the format of data representation classes:

public interface IEntidade 
{
    int Id { get; set; }
}

2

This implementation is coupling its business rules that I understand would be in the Person class with the code access to the database. It is interesting to even separate things as you came to do but the inheritance separates things as to reading the code but logically not, for this reason the indicated is to use composition instead of inheritance. In this case you would still have the same classes, but the Person class would be passed as a parameter to Personcrud or Personcrud could be injected into the Person class. I could not find links explaining the famous rule "Prefer composition instead of Heritage" with C#, but this link aq is cool!

  • I’ll take a look...

1

The person class represents a Person and a "crud" represents its repository of people, they should not have a dependency based on inheritance as they represent distinct objects.

One represents a real-world person and the other represents the place where you store information. You are concentrating the details of the people repository together with the person class. A better alternative would be to use abstract or even Generics classes for the positorios and inherit a differentiated repository for each instance of object to be stored.

This will reduce the coupling and allow a lower maintenance level in the long term. Another problem is that because you use the person class to inherit from the repository, if you’re using layered architectures, you’ve just complicated life to ensure that the higher layers don’t access the Reposorios directly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.