模板方法模式,其中每个实现需要不同的参数
本文关键字:参数 实现 模式 模板方法 | 更新日期: 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一个检查/投票:)