2013-08-01 3 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); 

Главное, чтобы определить реальное абстракции и постройте свою систему из них, объединив их разумными способами. Разделение проблем является частью этого процесса.

0

Это подсказка, что ваш класс «знает слишком много». Класс Administrator должен знать только, что касается администратора. Он не должен иметь возможность запрашивать базу данных и извлекать объекты.

Вы должны изучить repository pattern. Попробуйте разложить приложение на несколько слоев. Например, у вас может быть класс DataRepository, основной задачей которого является запрос и обновление объектов базы данных.

Смежные вопросы