C#模型 - 关注点分离?

时间:2013-08-01 14:52:47

标签: c# oop model separation-of-concerns

我有一个具有其属性的模型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();
    } 
}

2 个答案:

答案 0 :(得分: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 );

关键是识别真正的抽象并通过合理的方式将它们构建起来。分离出问题是该过程的一部分。

答案 1 :(得分:0)

这是暗示你的班级"知道太多"。 Administrator类应该只知道管理员关注的内容。他不应该能够查询数据库并检索实体。

您应该查看Read this answer.。尝试将您的应用程序分解为多个层。例如,您可以拥有一个DataRepository类,其主要关注点是查询和更新数据库实体。