سؤال

Having the following classes:

Person.cs

namespace Project.Domain
{
    public class Person
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public decimal Money { get; set; }

        public decimal CreditScore { get; set; }

        public Person()
        {
            Money = 0;
            CreditScore = 0;
        }

        public void RandomCreditScore()
        {
            CreditScore = Random.GetRandomDecimal();
        }
    }
}

PersonService.cs

namespace Project.Service
{
    public class PersonService
    {
        public void Save(Person person)
        {
            personRepository.Save(person);
        }

        public void Save(PersonViewModel personViewModel)
        {
            Person person = PersonAssembler.Assemble(personViewModel);

            if (personViewModel.randomCreditScore)
                person.RandomCreditScore();

            personRepository.Save(person);
        }

    }
}

PersonController

namespace Project.Controllers
{
    public class PersonController
    {

        public ActionResult Create(PersonViewModel personViewModel)
        {
            Person person = PersonAssembler.Assemble(personViewModel);

            if (personViewModel.randomCreditScore)
                person.RandomCreditScore();

            personService.Save(person);
        }

        public ActionResult CreateAlternative(PersonViewModel personViewModel)
        {
            personService.Save(personViewModel);
        }

    }
}

And having a view in which a user can input the name, money and checkbox "set a random credit score"; which of the two controller methods would be preferred? Create or CreateAlternative?

In Create we manage the conversion from the view-model to the model in the controller and we avoid the service layer to have to know the view-model, which I think is a good thing. But on the other hand we are giving the controller the responsibility to know when to set a random credit score, given the user input.

In CreateAlternative well.. It's the opposite.

Another alternative would be to make the assembler handle the logic of when to calculate a random credit score, but I've haven't seen this much.

Is one of this alternatives a better option? Is there any added advantage of using any of them?

هل كانت مفيدة؟

المحلول

You can introduce dedicated type for person creation data.

public class NewPerson
{
    public Person Person { get; set; }
    public bool UseRandomCreditScore { get; set; }
}

Controller will be responsible for "mapping" viewmodel data into "business" data and pass it to the service.

public ActionResult Create(PersonViewModel personViewModel)
{
    var newPerson = new NewPerson
    {
        Person = PersonAssembler.Assemble(personViewModel),
        UseRandomCreditScore = personViewModel.randomCreditScore
    };

    personService.Save(newPerson);
}

In service

public void Save(NewPerson newPerson)
{
    var person = newPerson.Person;
    if (newPerson.UseRandomCreditScore)
    {
        person.RandomCreditScore();
    }

    personRepository.Save(person);
}

Dedicated type will "explicitly" tell others what data required for person creation.
Because viewmodel responsibility to have data prepared for the client side and it can contain some data not related to user creation.

This approach will protect business logic from possible change in the way how person displayed on the client side (viewmodel)

نصائح أخرى

Albeit a video-response is atypical (and might be voted down for no other reason), the best answer is if you watch this Robert C. Martin video on MVC (classic and for web), as his explanation will somehow click on your brain and it'll all make sense. After that point, you will just intuitively do as told (because there's no other real way to actually do it that still makes sense). Notice that MVC part starts at min 27:30 https://m.youtube.com/watch?feature=youtu.be&v=o_TH-Y78tt4&t=1650

Trying to explain it in text might feel more like an imposition rather than the one and only choice after comparing the alternatives as shown on video.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top