2013-08-01 155 views
1

我有一个模型Administrator,它有它的属性,但它也包含许多静态方法,它们并不真正与当前对象本身有任何联系,例如GetByCredentials(string username, string password);。是否有可能将静态方法分割到其他地方,并尽可能地纯粹对象?C#模型 - 分离关注?

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(); 
    } 
} 

回答

1

有几个选择这里,更主要的是,C#类分离的担忧工具。

最明显的是捕捉这些东西在自己的抽象(S)。例如,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); 

的关键是要找出真正的抽象,并通过合理的方式将它们组合起来,从而构建您的系统。分离问题是这一过程的一部分。

0

这是暗示你的班级“知道太多”。管理员类应该只知道管理员关心什么。他不应该能够查询数据库并检索实体。你可以看看repository pattern。尝试将你的应用分解成多个层次。例如,您可以拥有一个DataRepository类,其主要关注点是查询和更新数据库实体。