模板方法模式,其中每个实现需要不同的参数

本文关键字:参数 实现 模式 模板方法 | 更新日期: 2023-09-27 18:02:07

我有一个需要身份验证算法的基抽象类。我有两个实现,一个将散列密码并将其与存储的散列进行比较,另一个将使用windows活动目录。

但在实际做哈希检查或windows身份验证之前,我有额外的工作流逻辑,必须绝对实现。因此,像failedPasswordCount, lastAuthenticationAttemptDate, IsUserApproved等东西必须始终以相同的方式修改或使用,无论认证算法如何。

在我看来,这个问题似乎可以使用模板方法模式来解决,除了,实现我的两个身份验证方法所需的信息是不同的,这取决于使用哪一个。

public abstract class User
{
    public bool Authenticate() // my template method
    {
        lastAuthenticationAttemptDate = DateTime.UtcNow();
        if(IsUserApproved)
        {
            if(DoAuthenticate()) // implemented by childs
            {
                return true;
            }
            else
            {
                failedPasswordCount++;
                return false;
            }
        }
    }
    public abstract DoAuthenticate();
}
public UserWindowsLogon : User
{
    public override bool DoAuthenticate(string windowsDomain, string password)
    {
         ...
    }
}
public UserApplicationLogon : User
{
    public override bool DoAuthenticate(string password)
    {
         ...
    }
}
解决这个问题的最好方法是什么?有没有另一种已知的模式已经解决了这个问题?或者有人有好主意吗?

模板方法模式,其中每个实现需要不同的参数

你可以这样保持你的基接口的"DoAuthenticate()"没有参数

public UserWindowsLogon : User
{
    public string windowsDomain;
    public string password;
    public override bool DoAuthenticate()
    {
         // Check and use windowsDomain/password values here
    }
}

public UserApplicationLogon : User
{
    public UserApplicationLogon(string password) : base()
    {
         this.password = password;
    }
    private string password;
    public override bool DoAuthenticate()
    {
         // use password value here
    }
}

并提供在实例化User派生对象时使用的参数值。

假设您的客户端代码知道该做什么(应该应用哪些实际参数),您可以轻松地在身份验证周围引入类层次结构,从而使在该层次结构的基类上声明契约成为可能。

public abstract DoAuthenticate( AuthenticationContext context );
...
public UserWindowsLogon : User
{
  public override bool DoAuthenticate( AuthenticationContext context )
  { 
     if ( context is UserWindowsAuthenticationContext )
     {
        // proceed
     }
  }
}
public UserApplicationLogon : User
{
  public override bool DoAuthenticate( AuthenticationContext context )
  {
     if ( context is UserAplicationAuthenticationContext )
     {
        // proceed
     }
   } 
}
public abstract class AuthenticationContext { }
public class UserWindowsAuthenticationContext : AuthenticationContext
{
   public string windowsDomain;
   public string password;
}
public class UserApplicationAuthenticationContext : AuthenticationContext
{
   public string password;
}

这是一个策略模式(其中策略是身份验证/验证机制)遇到复合模式的例子

验证通常是一个复合模式。当你把它分开时,你想把你想做什么你想怎么做分开,你得到:

If foo is valid
then do something.
这里我们有一个抽象是有效的

我只是写了,基本上,你的情况。如果你觉得这个答案是最棒的,那么给IT一个检查/投票:)