SRP 应用于工作流程示例:如何以合理的方式构建类
我在决定班级职责时遇到问题。
我有 3 个 html 表单:
- 对于每个表单,都有一个 html 模板,其中包含一些文本和要包含的表单的标记
- 每个表单都需要进行验证,如果出现错误,则需要验证模板和 (1) 中的表单重新显示,并带有一些错误消息。只有一些字段在不同的表单中是通用的。
- 如果没有错误,则需要邮寄结果消息。每个表格都有一个结果邮件模板。
我发现很难为这个问题决定一个好的班级方案。一种可能性是按功能分离类
- CheckFormData:检查表单数据
- DisplayForm:显示有/无错误的表单(或也将其分开?)
- EmailForm:电子邮件表单。
我对此不确定。关于一种特定形式的领域的知识分散在各个类别中。
有一些工作流程。也许我还应该有一个工作流程类:
class FormSubmitWorkFlow
{
function start()
{
$this->displayForm->render();
}
function processFormData($data)
{
$this->checkForm->setData($data);
if (!$this->checkForm->isValid()) {
$errors = $this->checkForm->getErrors();
$this->displayForm->setData($data)->setErrors($errors)->render();
} else {
$this->emailForm->setData($data)->email();
}
}
function setDisplayForm(DisplayForm $df)
{
$this->displayForm = $df;
}
function setCheckForm(CheckForm $cf)
{
$this->checkForm = $cf;
}
function setEmailForm(CheckForm $ef)
{
$this->emailForm = $ef;
}
}
对于每种表单类型(记住,有 3 种),我需要一个
CheckForm
、EmailForm
和DisplayForm类。
3*3 = 9 个类 + 3 个基类 = 12 个类。
此外,您希望将正确的 CheckForm 子类和 EmailForm 子类注入到工作流程中,它们都需要具有相同的表单类型。也许我们需要为此创建一个 FormWorkFlowFactory。这总共有 13 个类。
现在我感觉我正在做一些非常错误的事情。 如果我将 FormSubmitWorkFlow
作为模板方法类,我可以只创建 3 个子类,但每个子类都会混合不同的职责。
您如何改进这一点,您能否激发您的答案,即什么方法可以引导您找到答案?
编辑:虽然当前唯一的答案很有用,但它会很好看到一些同意它的人的投票,或者我想听到社区更好的解决方案。我是唯一一个对这个答案投赞成票的人。这个问题可能需要更多的输入,所以请随意提供:-)
I have a problem with deciding about class responsibilities.
I have 3 html-forms:
- For each form there is a html template containing some text and a marker for the form to be included
- Each form needs to be validated, if there is an error the template and the form from (1) needs to redisplayed, together with some error messages. Only some fields are common across the different forms.
- If there are no errors a result message needs to be mailed. For each form there is a result mail template.
I find it very hard to decide on a good class scheme for this problem. One possibility is to separating classes by functionality
- CheckFormData: checking form data
- DisplayForm: display form with/without errors (or separate this too?)
- EmailForm: emailform.
I am uncertain about this. Knowledge about the fields of one particular form are dispersed accross the various classes.
There is some workflow. Maybe I should also have a workflow class:
class FormSubmitWorkFlow
{
function start()
{
$this->displayForm->render();
}
function processFormData($data)
{
$this->checkForm->setData($data);
if (!$this->checkForm->isValid()) {
$errors = $this->checkForm->getErrors();
$this->displayForm->setData($data)->setErrors($errors)->render();
} else {
$this->emailForm->setData($data)->email();
}
}
function setDisplayForm(DisplayForm $df)
{
$this->displayForm = $df;
}
function setCheckForm(CheckForm $cf)
{
$this->checkForm = $cf;
}
function setEmailForm(CheckForm $ef)
{
$this->emailForm = $ef;
}
}
For each form type (remember, there are 3 of them) I would need a
CheckForm
,EmailForm
andDisplayForm
class.
3*3 = 9 classes + 3 base classes = 12 classes.
Also, you want to inject the right CheckForm-subclass and EmailForm-subclass into the workflow, they all need to be of the same form type. Maybe we need to create a FormWorkFlowFactory for this. This adds up to 13 classes.
Now I got the feeling I am doing something horribly wrong.
If I had FormSubmitWorkFlow
as a Template Method class, I could just create 3 subclasses, but each subclass would mix different responsibilities.
How could you improve this, and could you motivate your answer, i.e. what method leads you to your answer?
edit: although the only current answer is useful, it would be nice to see some votes from people that agree with it, or I would like to hear better solutions from the community. I am the only one who upvoted this answer. This question could use more input, so feel free to provide so :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定这是否能回答您的问题,但显然 SRP 的目标是编写代码,这样如果您必须更改某些内容,则只有一个原因。就像如果你的车有 SRP,那么就不会有一个可以调节温度和打开或关闭车窗的课程。那就违反了原则。在这种情况下,你似乎做得对。是的,课程很多,但替代方案就是很多混乱。除非有一种方法可以创建一个单独的类来验证表单(这实际上应该是可能的,具体取决于您需要哪种验证)。
如果您创建了一个验证类,您可以在其中添加一系列期望值并查看它们是否匹配,那么您可能会拥有更多的整体类,但我认为它的耦合度会低得多。请告诉我我的理解是否正确。
I'm not sure if this will answer your question or not but obviously the goal of SRP is to write your code so that if you have to change something, it's for one reason only. Like if your car had SRP then there wouldn't be a class that adjusted the temperature and also put the windows up and down. That would violate the principle. In this case you seem to be doing it right. Yes it's a lot of classes but the alternative is a lot of confusion. Unless there was a way that you could create a single class that would validate the forms (which really should be possible depending on what sort of verification you need).
If you created a verification class where you could just add a chain of expected values and see if they matched then you would probably have more overall classes but I think that it would be far less coupled. Let me know if I understood you correctly or not.