2013-08-01 152 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類,其主要關注點是查詢和更新數據庫實體。