Save legacy data in C#

Asked

Viewed 224 times

0

I have the following classes:

public class Aluno
{
    public String Nome { get; set; }
    public String Ra { get; set; }
    public Decimal NotaB1 { get; set; }
    public Decimal NotaB2 { get; set; }


    public Decimal getMedia()
    {
        return (NotaB1 + NotaB2) / 2;
    }

}

 public class AlunoTecnologo : Aluno
{
    public Decimal NotaPim { get; set; }

    public Decimal getMedia()
    {
        return NotaPim * 0.2m + base.getMedia();
    }
}

I’m simulating the persistence of the data in a comic book, so I created the next class where I create a list to save the students in memory:

public class AlunoDao
{
    private List<Aluno> alunos;

    public AlunoDao()
    {
        alunos = new List<Aluno>();
    }

    public void Adicionar(Aluno aluno)
    {
        alunos.Add(aluno);
    }

    public List<Aluno> Listar()
    {
        return new List<Aluno>(alunos);
    }
}

But when saving a AlunoTecnologo in that list, the average is calculated using the class method Pupil and not of class AlunoTecnologo where an extra note is inserted. Here is an example of how the code looks:

static void Main(string[] args)
    {
        Aluno vizu = new Aluno()
        {
            Nome = "Joao Vizu",
            Ra = "N300361",
            NotaB1 = 7.5M,
            NotaB2 = 10M
        };

        AlunoTecnologo lais = new AlunoTecnologo()
        {
            Nome = "Lais Silva",
            Ra = "545454",
            NotaB1 = 7.5M,
            NotaB2 = 10M,
            NotaPim = 9M
        };

        AlunoDao dao = new AlunoDao();

        dao.Adicionar(vizu);
        dao.Adicionar(lais);

        foreach (Aluno aluno in dao.Listar())
        {
            Console.WriteLine($"Nome: {aluno.Nome}\tNotaB1: {aluno.NotaB1}\tNotaB2: {aluno.NotaB2}\tMedia: {aluno.getMedia()}");
        }

        Console.ReadKey();
    }

What should I do so that I can add to this list the correct data of each student, following the inheritance? I would have to create a DAO class for the AlunoTecnologo?

2 answers

2


In this case you should not create a new DAO, after all you are using inheritance. One can even ask if you should have this inheritance because of liskov principle, but it depends on some factors we don’t know about your problem. I will consider that inheritance is really necessary (I think modeling is wrong, but it is a mistake that almost everyone makes and they think is right so I will not focus on this point).

The DAO is to take care of the students, no matter which ones, so it is correct. What you need is polymorphism, so the correct method will be called.

Let’s fix some other code problems? I won’t fix all, for example I won’t create builder.

using static System.Console;
using System.Collections.Generic;

public class Program {
    public static void Main(string[] args) {
        var vizu = new Aluno() {
            Nome = "Joao Vizu",
            Ra = "N300361",
            NotaB1 = 7.5M,
            NotaB2 = 10M
        };
        var lais = new AlunoTecnologo() {
            Nome = "Lais Silva",
            Ra = "545454",
            NotaB1 = 7.5M,
            NotaB2 = 10M,
            NotaPim = 9M
        };
        var dao = new AlunoDao();
        dao.Adicionar(vizu);
        dao.Adicionar(lais);
        foreach (Aluno aluno in dao.Listar()) WriteLine($"Nome: {aluno.Nome}\tNotaB1: {aluno.NotaB1}\tNotaB2: {aluno.NotaB2}\tMedia: {aluno.Media}");
    }
}

public class Aluno {
    public string Nome { get; set; }
    public string Ra { get; set; }
    public decimal NotaB1 { get; set; }
    public decimal NotaB2 { get; set; }
    public virtual decimal Media => (NotaB1 + NotaB2) / 2;
}

 public class AlunoTecnologo : Aluno {
    public decimal NotaPim { get; set; }
    public override decimal Media => NotaPim * 0.2m + base.Media;
}

public class AlunoDao {
    private List<Aluno> alunos;
    public AlunoDao() => alunos = new List<Aluno>();
    public void Adicionar(Aluno aluno) => alunos.Add(aluno);
    public List<Aluno> Listar() => new List<Aluno>(alunos);
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

I’ve made changes that use a cleaner, more modern way to code in addition to following C#’s naming patterns. But what matters to you there is to make the method virtual, so it can be chosen between the actual object method and not the general type that is declared in the list. Study the subject to better understand the mechanism.

I made this property because it is the most appropriate and idiomatic way of C#, the way asked in the question is something of another language.

In a database you will have to have a single table with all fields used in all tables derived from Aluno. Or have separate tables, then it falls into what I said maybe inheritance is not the case. If you make several tables you should not use inheritance. People do not understand the implication of inheritance and how this cannot be performed correctly in a database (it can, but becomes meaningless, you will have a table only with references to others). It may be that what you want is to implement papers and not heritage. This kind of heritage does not always fit well in the real world and makes it easy to make some mistakes, if it does not violate Liskov.

If you leave the inheritance there would be the case of having 2 or more Daos or adopt something more suitable because there happens to have things completely separate, Ina that related, you happen to have a relational model.

Sometimes I question the use of Daos, in this case it is clear that it is using as abstraction and at the moment it is only in memory but one day wants to be able to switch to the database. The problem is that the model that worked in memory will not always work in the database, which is why I say that generalization is not as simple as people think. I explain in detail about another answer.

0

Yes you need to create another "Dao" and also another table.

See that the inheritance works well, turns out that in your Dao you a list of Aluno, and he accepts a AlunoTecnologico because this inherits from Aluno, but the object will be treated as Aluno, that is, will use the method getMediaof Aluno, so it doesn’t calculate how you expect, and nor should it, because the class Aluno doesn’t have the property NotaPim, obviously would make a mistake :)

Also, speaking in BD, your "Student" table should not have a "Notapim" attribute, so you will lose this value.

For your example, the simplest solution to implement/understand can be to create two tables and two "DAO" classes, for Student and Student. You didn’t say which database you’re using, but in general BD doesn’t implement this inheritance structure, so better each separate entity.

Of course you can make a solution more elaborate and more correct from a model point of view:

Create the table "Student", the table "Learner" and this have only the attributes that do not have in "Learner", ie "Notapim", and add a key to "Learner".

Note that I’m assuming you’re using a relational database (mysql, sql-server, oracle, etc.) Hence put the logic to record in both tables and also recover the value of both in "DAO", but this would be much more work, as you are studying C#, maybe not the best option for this time.

Browser other questions tagged

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