Witam szanowne grono forumowiczów,
Ktoś odkopał wczoraj temat z przed 2 lat (Zadanie rekrutacyjne) i akurat jeden post rzucił mi się w oczy. Chciałbym poruszyć kilka kwestii odnośnie proponowanego rozwiązania, dla czytelności przekleje cały kod tutaj.
public class User
{
public Guid Id { get; protected set; }
private decimal _balance;
public decimal getBalance => _balance;
private static readonly object _lock = new object();
public void Withdraw(decimal value)
{
lock (_lock)
{
if (value >= balance)
{
_balance -= value;
}
}
}
}
public static class UserService
{
public static ActionResult Perform_Withdraw_Logic(User user, decimal value)
{
if (value <= 0)
{
return new BadRequestResult("Amount of money to withdraw must be greater than 0");
}
if (value > user.getBalance)
{
return new BadRequestResult("You've not enough money");
}
user.Withdraw(value);
return new OkRequestResult("Money has been withdrawn successfully");
}
}
public class Controller
{
public HomeController : Controller
{
[Authorize]
public ActionResult WithdrawMoney([FromBody] WithdrawCommand)
{
var user = db.Single(c => c.Id == WithdrawCommand.Id);
if (user == null)
{
return new BadRequestResult("User not found");
}
return UserService.Perform_Withdraw_Logic(user, WithdrawCommand.Amount);
}
}
}
Otóż zastanawia mnie kilka kwestii.
- Czy klasa User jest w tym kontekście modelem? Co tam robi metoda Withdraw? W podejściu ktore sam praktykuję modele zawierają propertisy, a logika operacji jakie mogą zostać wykonane na modelu znajduje się w serwisie.
- Jak zaimplementowany jest UserService? Czy nie powinien on implementować serwisu IUserService kóry byłby wstrzykiwany do Controllera i stamtąd wywoływane odpowiednie metody?
- Czy przez okres 2 lat coś się zmieniło w temacie architektury? Od momentu kiedy został utworzony temat Zadania rekrutacyjnego do dzisiaj.
4. Jak w podejściu które sam praktykuje zabezpieczyć się przed dostępem wielu wątków do jednego zasobu? Czy proponowany poniżej sposób jest poprawny?
public class UserService : IUserService
{
private readonly DbContext _db;
private object _lock = new object();
public UserService(DbContext db)
{
_db = db;
}
public void Update(User user)
{
lock(_lock)
{
_db.Users.Update(user);
}
}
}