2013-08-01 2 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#을 클래스 문제를 분리 도구 점이다.

가장 확실한 것은 자신의 추상화에서 이러한 것들을 캡처하는 것입니다. 예를 들어, 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); 

중요한 것은 실제 확인하는 것입니다 abstractions 그리고 합리적인 방법으로 결합하여 시스템을 구축하십시오. 관심사를 분리하는 것이 그 과정의 일부입니다.

0

이것은 수업이 "너무 많이 알고 있습니다"라는 힌트입니다. 관리자 클래스는 관리자와 관련된 사항 만 알고 있어야합니다. 그는 데이터베이스를 조회하고 엔티티를 검색 할 수 없어야합니다.

repository pattern을 조사해야합니다. 응용 프로그램을 여러 레이어로 분해 해보십시오. 예를 들어, 데이터베이스 엔터티를 쿼리하고 업데이트하는 것이 주된 관심사 인 DataRepository 클래스를 가질 수 있습니다.