我想为网站构建一个Register类。以下是我的用例 -
这是我想到的设计
Interface IRegister
{
string RegisterUser(string email, string password);
}
public class Register:IRegister
{
public string RegisterUser(string email, string password)
{
//Call IsUserExist and SentActivationEmail method internally
}
private bool IsUserExist()
{
}
private void SendActivationEmail()
{
}
}
我不想在IRegister中提及IsUserExist和SendActivationEmail方法,因此它仍然很简单。现在我如何强制实施一个开发人员来实现他/她应该使用IsUserExist和SendActivationEmail方法的Register类,并执行用例中提到的所有操作。这个设计是否违反了SRP原则?
答案 0 :(得分:2)
如果要强制开发人员使用这些方法,那么您应该使用受保护的抽象方法而不是接口来声明抽象类。然后定义强制执行这些方法,但开发人员可以随意实现它们。
public abstract class Register:IRegister
{
public string RegisterUser(string email, string password)
{
//Call IsUserExist and SentActivationEmail method internally
}
protected abstract bool IsUserExist();
protected abstract void SendActivationEmail();
}
话虽这么说,为了遵守SRP原则,我会将其中的电子邮件部分拉出到依赖的IActivationEmailer接口中。电子邮件和注册实际上是两种不同的行为,应该分开。
public interface IActivationEmailer {
void SendActivationEmail();
}
public abstract class Register:IRegister
{
private IActivationEmailer m_emailer;
protected Register(IActivationEmailer emailer){
// store emailer to field
m_emailer = emailer;
}
public string RegisterUser(string email, string password)
{
//Call IsUserExist and m_emailer.SentActivationEmail method internally
}
protected abstract bool IsUserExist();
}
答案 1 :(得分:0)
我同意Mikes的回答。稍微不同的方法是应用template method并让子类定义他们想要在注册时做什么(我不熟悉C#所以请耐心等待):
public abstract class Register:IRegister
{
public string RegisterUser(string email, string password)
{
if (this.IsUserExist())
{
//throw the error
}
else
{
this.performRegistration();
this.notifyUSer();
}
}
protected abstract bool IsUserExist();
protected abstract notifyUSer();
protected abstract performRegistration(){}
}
然后,正如迈克指出的那样,你可以定义:
public interface IActivationEmailer {
void SendActivationEmail();
}
public class CustomRegister
{
private IActivationEmailer m_emailer;
public CustomRegister(IActivationEmailer emailer){
// store emailer to field
m_emailer = emailer;
}
protected abstract bool IsUserExist(){...}
protected abstract notifyUSer() {this.m_emailer.SendActivationEmail();}
protected abstract performRegistration(){...}
}
所以基本上Register类正在定义注册过程中要遵循的步骤,但是它会让子类说明如何实现这些步骤。
HTH