我的设计遵循单一责任原则吗?

时间:2012-11-05 02:23:21

标签: c# oop design-patterns

我想为网站构建一个Register类。以下是我的用例 -

  1. 用户将提供电子邮件ID&注册密码
  2. 如果电子邮件ID已存在,则Register类将发送一条错误消息,指出此电子邮件已存在于我们的系统中
  3. 如果我们的系统中不存在电子邮件,则Register类将在用户电子邮件ID中发送激活电子邮件并向用户显示消息 - 已将一封激活电子邮件发送至他/ ser电子邮件
  4. 这是我想到的设计

    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原则?

2 个答案:

答案 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