C#模型-关注点分离
本文关键字:分离 关注点 模型 | 更新日期: 2023-09-27 18:25:53
我有一个模型Administrator
,它有自己的属性,但它也由许多静态方法组成,这些方法与当前对象本身没有任何联系,例如GetByCredentials(string username, string password);
。是否有可能将静态方法划分到其他地方,并使对象尽可能纯净?
示例
public class Administrator : Entity
{
// OBJECT START
public int Id { get; set; }
public DateTime CreatedDateTime { get; set; }
public DateTime UpdatedDateTime { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string PasswordSalt { get; set; }
public void SetNewPassword(string password)
{
var cryptoService = new PBKDF2();
this.Password = cryptoService.Compute(password);
this.PasswordSalt = cryptoService.Salt;
}
public override void OnBeforeInsert()
{
this.CreatedDateTime = DateTime.Now;
this.UpdatedDateTime = DateTime.Now;
this.SetNewPassword(this.Password);
}
public override void OnBeforeUpdate()
{
this.UpdatedDateTime = DateTime.Now;
}
// OBJECT END
// Now I have multiple static methods that do not really
// have anything to do with current object
public static Administrator GetByCredentials(string username, string password)
{
var db = new MainDataContext();
var admin = db.Administrators.SingleOrDefault(x => x.Username == username);
if (admin == null) return null;
ICryptoService cryptoService = new PBKDF2();
var hash = cryptoService.Compute(password, admin.PasswordSalt);
if (hash == admin.Password) return admin;
return null;
}
public static bool IsCurrentIpBanned
{
get
{
const int minutesBlocked = 5;
const int maxLoginCount = 5;
var db = new MainDataContext();
var loginCount = db.AdministratorAuthorizationLogs.AsEnumerable().Count(x => x.Ip == HttpContext.Current.Request.UserHostAddress && x.CreatedDateTime.AddMinutes(minutesBlocked) > DateTime.Now && x.IsSuccess == false);
return loginCount > maxLoginCount;
}
}
public static void LogSuccess(Administrator admin)
{
Administrator.Log(admin, true);
}
public static void LogFailure(Administrator admin)
{
Administrator.Log(admin, false);
}
private static void Log(Administrator admin, bool success)
{
var db = new MainDataContext();
db.AdministratorAuthorizationLogs.Add(new AdministratorAuthorizationLog
{
Username = admin.Username,
Password = admin.Password,
Ip = HttpContext.Current.Request.UserHostAddress,
IsSuccess = success
});
db.SaveChanges();
}
}
这里有几个选项,但最重要的是C#类是分离关注点的工具。
最明显的是在它们自己的抽象中捕捉这些东西。例如,GetByCredentials
作为不同类别Authority
或类似类别的(非静态)成员可能更好。该类只需要能够创建一个Administrator
类型。
您也可以使用扩展方法。一个可能的候选者是Log
,它以Administrator
为参数,并且只使用它上的公共设施。扩展方法在一个单独的类中定义,但允许您"像"使用它们是扩展类的成员一样使用它们,例如:
public static class AdministratorExtensions
{
public static void log( this Administrator admin, bool success ) { ... }
}
var admin = new Administrator();
admin.Log( true );
关键是识别真正的抽象,并通过合理的方式组合它们来构建系统。分离关注点是这一过程的一部分。
这暗示您的类"知道的太多了"。Administrator类应该只知道与管理员有关的内容。他不应该能够查询数据库和检索实体。
您应该研究一下存储库模式。尝试将应用程序分解为多个层。例如,您可以有一个DataRepository类,它的主要关注点是查询和更新数据库实体。