Мнение о дизайне логического слоя бизнеса для окна и веб-приложения
-
05-10-2019 - |
Вопрос
Мне нужны мнения по выбору, какие подписи для моего веб-сайтов бизнес-слоя:
Функция Void CreateUser (Компания UserCompany, String Name ...)
или
Функция void createuser (int comproyid, string name ...)
Если это на основе окна, я бы выбрал функцию, чтобы принять объект вместо INT, потому что, поскольку компания уже загружена в форму окна, почему бы просто не использовать ее. Кроме того, я думаю, что бизнес-слой должен принимать бизнес-объекты, и это в безопасности типа (предотвращение случайно проходить в 0 или -1).
Но с другой стороны, если это веб-приложение, только идентификатор будет загружен на клиентские сайты. Таким образом, это вроде избыточное для загрузки объекта компании, потому что в конце концов только CompanyID будет сохранена в DabaseBase в любом случае.
Надеюсь, мое описание не слишком запутано = P Спасибо за чтение.
Решение
Я думаю, что вы ответили на ваш собственный вопрос, это зависит от слоя презентации, который вы используете. Но когда вы хотите сохранить этот бизнес-уровень, вам придется пойти с идентификатором.
Вот еще одна идея. Я лично люблю обернуть все мутации на классы, которые я называю командами. Вы могли бы, например, иметь 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);
}
}
Надеюсь, это поможет.