问题
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 :-)
回答1:
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.
来源:https://stackoverflow.com/questions/1792651/srp-applied-to-a-workflow-example-how-to-structure-the-classes-in-a-sensible-wa