Мнение о дизайне слоя бизнес-логики для оконного и веб-приложения - PullRequest
1 голос
/ 24 сентября 2010

Мне нужно несколько мнений по поводу выбора подписей для моей функции веб-уровня:

void CreateUser (Company UserCompany, имя строки ...)

или

function void CreateUser (int CompanyID, имя строки ...)

Если это окно, я бы выбрал функцию для взятия объекта вместо int, потому что, посколькукомпания уже загружена в форму окна, почему бы просто не использовать ее.Кроме того, я думаю, что бизнес-уровень должен принимать бизнес-объекты и его тип безопасен (предотвращая случайный переход в 0 или -1).

Но с другой стороны, если это веб-приложение, будет загружен только идентификатор.на клиентские сайты.Таким образом, это несколько избыточно для загрузки объекта компании, потому что в конечном итоге только база данных будет сохранена в базе данных.

Надеюсь, мое описание не слишком запутанное = P Спасибо за чтение.

1 Ответ

0 голосов
/ 24 сентября 2010

Я думаю, что вы ответили на свой вопрос, это зависит от используемого вами уровня презентации. Но если вы хотите, чтобы этот бизнес-уровень был универсальным, вам придется использовать идентификатор.

Вот еще одна идея. Мне лично нравится заключать все мутации в классы, которые я называю командами. Например, вы можете иметь CreateUserCommand, который наследуется от базовой команды. Это позволит вам использовать его следующим образом (я предполагаю, что C # здесь):

var command = new CreateUserCommand();

command.UserCompanyId = companyId;
command.UserName = name;

command.Execute();

При включении этой логики в команду очень хороший шаблон. Это позволяет вам поместить один вариант использования в одну команду. Особенно, когда количество логики в команде растет, вы оцените этот шаблон, но я обнаружил, что он очень эффективен и для операций CRUD.

Этот шаблон также позволяет абстрагировать транзакционную модель в базовом классе. Базовый класс может обернуть вызов для выполнения в транзакции базы данных. Вот простая реализация:

public abstract class CommandBase
{
    public void Execute()
    {
        this.Validate();

        using (var conn = ContextFactory.CreateConnection())
        {
            conn.Open();
            using (var transaction = conn.BeginTransaction())
            {
                using (var db = ContextFactory.CreateContext(conn))
                {
                    this.ExecuteInternal(db);

                    db.SubmitChanges();
                }

                transaction.Commit();
            }
        }
    }

    protected virtual void Validate() { }

    protected abstract void ExecuteInternal(YourDataContext context);
}

И вот как CreateUserCommand будет выглядеть:

public class CreateUserCommand : CommandBase
{
    public int UserCompanyId { get; set; }
    public string UserName { get; set; }

    protected override void ExecuteInternal(YourDataContext context)
    {
       this.InsertNewUserInDatabase(context);
       this.ReportCreationOfNewUser();
    }

    protected override void Validate()
    {
        if (this.UserCompanyId <= 0) 
            throw new InvalidOperationException("Invalid CompanyId");
        if (string.IsNullOrEmpty(this.UserName))
            throw new InvalidOperationException("Invalid UserName");
    }

    private void InsertNewUserInDatabase(YourDataContext context)
    {
       db.Users.InsertOnSubmit(new User()
       {
          Name = this.UserName,
          CompanyId = this.CompanyId
       });
    }

    private void ReportCreationOfNewUser()
    {
        var message = new MailMessage();
        message.To = Configuration.AdministratorMailAddress;
        message.Body = "User " + this.Name + " was created.";

        new SmtpClient().Send(message);
    }
}

Надеюсь, это поможет.

...