With user registration example I intentionally took a widely spread and simple domain that everyone, I guess, is familiar with. I want to demonstrate how it can be viewed differently, with object-thinking in mind. This post can be viewed as a sequence of steps that I take when modeling some domain. First, let’s talk about forms Forms nowadays are utilized as a tool for data validation with an intention to make something useful with this data. Quite often I see that validation resides aside from business-logic. In this case data is treated as being passive: first, validate it, then do this, and then do that. Well, it’s great, and it’s called . The next step is to move the validation logic, , to those . This is what DDD teaches us to do. In this case forms are just a tool for letting a user to mutate some data. But there are cases when form is a full-fledged domain concept, that just happens to look like web-form at some steps. Procedural programming intrinsic to domain concepts value-objects and entities My domain **_Verbal (ok, textual) description_**In the very beginning it’s useful to come up with a basic description of your application, of what it does, what is important, what is a domain it operates in, what are some real-life application examples. Here it is. My domain is a registration of users. They open a page, see a registration form, fill it and then submit. Then confirmation email is sent on a email address, indicated while filling the form. It contains a confirmation link with a secret token, so if the user follows this link, it means that he filled an email that really belongs to him. So clicking this link completes the process of registration: a new user shows up in a system. I’m not trying to model this domain in its entirety though. It’s just a sketch. I start decomposing with a semantic net. It helps me in discovering basic objects. Moreover, it visually represents what’s going on and how things are connected with each other. It’s quite trivial in this example. Semantic net Simple semantic net of user registration domain While drawing a sketch, I keep in mind . In practice it mainly results in the absence of . Why? Because of a ’s human metaphor. Or ’s . Because of what objects are all about in OOP. Objects are like smart and independent grown-ups which don’t need to be told how to do what they are expected to. Only nouns, no “services” object metaphors service-classes David West Alan Kay cell metaphor **_Understanding the domain rules_**Just like in , I use the same technique. I plunge into the past to see how some particular domain looked like then. identifying service boundaries So let’s consider some paper form. It could be some application form or registration form, just whatever. What it was like to register somewhere? You took the form. It was printed on a typewriter. You took a pen. Filled it. Then you gave it back to some kind of a secretary. He or she reviewed it, probably noted some typos or mistakes immediately, checked your passport to make sure you were who you said you were and than kept it for further validation that might require couple of more days. Then you could’ve come back several days later to find out how’s your form. Or you simply could receive a letter with results. How to model a domain **_A few words on how to model the domain rules_**What’s different now, when there are no typewriters and no secretaries? The forms still need to be displayed and validated. Who should do that? Well, long story short, object thinking implies that a form itself should. Right now we’re modeling the behavior intrinsic to the process of registration. It has nothing to do with printers, any validators, , for now it’s just a registration form, a token and an email. OK, and a visitor with a user, which just happened to end with “or” and “er”. Nothing prevents these classes to utilize all they need to implement their responsibilities though. Moreover, it’s encouraged that objects own all the necessary resources: database connections, external resource, caching resources. If it’s too much for one class — no problem, decorators are the way to go. An example of this concept is an : your objects cease being manipulated, they decide what to do themselves. And the same situation is all over the place. Services are inverted. They don’t operate upon objects anymore.So our entities’ responsibilities could look like the following. Registration form is responsible for displaying itself, validating and saving itself. Email is responsible for sending itself. To get a full picture we should come up with and elaborate a set of . other “er”s or “or”s ORM user stories **_User stories_**Which user stories constitute a process of registration? What about the following: A visitor requests a form and fills it. I can derive from this story that a form should have a responsibility to display itself. A form makes sure that all fields are valid. Validation process requires more elaboration. Remember what I wrote about how registration worked fifty years ago? A process of validation included that a secretary needed to check that you were who you said you were, so you showed him or her your passport. Today an email serves as a passport. We send a letter on an email that a visitor filled in that form, and he or she should confirm it, and this process is included in a term “validation”.So any registration inevitably includes an asynchronous part. There’s no sense in trying to validate everything synchronously then. What I leave in synchronous validation are some lightweight checks which when violated won’t ever let a registration to succeed. What are these checks? Well, for example that the birth date is less than today or a year ago. The birth date should seem to be real. Or that an email is -compliant. So if all such checks pass successfully, I say that the form can be .Some asynchronous checks might be paralleled, some should be only sequential. Running ahead I can say that such checks could be implemented as . And each one of them requires its own user story. That’s how the whole process could be illustrated: RFC822 accepted saga Form validation ending with registration of a user If a form is valid, it registers a visitor (keep in mind that objects are active!), so it becomes a user. So this story card unveils another form’s responsibility: user registration. Next elaborated validation user stories could go. I don’t want to delve too deep here and confine myself with only those that concern email confirmation. Here they are: If synchronous validation is ok, compose a confirmation email and send it to a visitor. A interaction diagram for composing and sending a confirmation email Apparently, an email should be composed with a help of a form, after all it’s an for it. But an email should possess all the resources to be able to send itself. information expert Visitor follows a confirmation link from an email and becomes a user. A interaction diagram for confirming an email address Here a form delegates confirmation to the token since it knows better how to confirm an input token string. If it’s ok, then a form registers a new user. It’s a common flow, reflecting a domain when viewed with object-thinking in mind: one entity creates another, and so on. . Entities (i.e., aggregates) don’t pop up themselves Along with user stories discovering, I could create . Even if talking about CRC cubes (a concept derived from CRC cards, I first encountered it in David West’s Object Thinking), the side that works best for me is the one with responsibilities. So I walk through all user stories involving a particular object and collect its responsibilities. They represent services that my object can provide, and they form an object’s contract. I won’t delve into formal representation of CRC cubes, let’s just move to the code. CRC cards CRC cards Code OK, so I look at my responsibilities and see that my form should be able to: display itself; validate itself; compose a confirmation email, as a part of validation; confirm an email, as part of validation as well; register a user. So these are the candidates to form an object’s contract. Keep in mind that the following code is just a representation of ideas and principles presented above. It’s more than a pseudo-code, but less than a production code. **_Displaying a form_**I want my registration form to be responsible only for displaying data, leaving decoration to someone else. I don’t think that it’s a good idea to let the form be aware of every representation detail though, so I hope for a collaboration from specific classes. It might look like the following: _// an entry point. It might also be a controller action._ display(){( RegistrationForm( UUID(), RegistrationFormDataStorage()))->display();} public function new new new And the form method itself. The implementation could be in . this spirit RegistrationForm{ ; class /*** @var $id UUID*/ private $id _/\*\* \*_ **_@var_** _$storage DataStorage \*/_ **private $storage**; **public function** \_\_construct(UUID $id, DataStorage $storage) { $this->**id** \= $id; $this->**storage** \= $storage; } **public function** display() { (**new** RegistrationWebForm( **new** HiddenElement( $this->**id**\->value() ), **new** NameElement(), **new** PassportElement(), **new** EmailElement() )) ->display(); } } Accepting a form accept( $data){ {( RegistrationForm( FixedUUID($data[ ]), RegistrationFormDataStorage()))->accept( Name($data[ ]), Passport( PassportNumber($data[ ]), PassportIssuedAt($data[ ]), PassportIssuedWhere($data[ ])), Email($data[ ]));} (Exception $e) {( ErrorPage())->display();} public function array try new new 'id' new new 'name' new new 'passport_number' new 'passport_issued_at' new 'passport_issued_where' new 'email' catch new (**new** RegistrationAcceptedPage())->display(); } Again, it was how an entry point could look like. Here is implementation of method: RegistrationForm->accept() accept(IValidatableElement $name,IValidatableElement $passport,IValidatableElement $email){$this-> ->transactionally( () ($name, $passport, $email) {$id =$this-> ->save([ => $name->value(), => $passport->value(), => $email->value(),]);$this-> ->appendFormAcceptedEvent($id);});} public function storage function use storage 'name' 'passport' 'email' storage Mind a event that’s transactionally stored in a database. I don’t want to perform all logic in one run since I don’t want to abuse DDD’s “One aggregate — one transaction” rule of thumb. I have a separate handler that handles that event; it composes a confirmation email. Form accepted Compose a confirmation email composeConfirmationEmail(UUID $formId){( RegistrationForm($formId, RegistrationFormDataStorage()))->composeConfirmationEmail( SmtpClient(), EmailConfirmationEmailHeader(), EmailConfirmationEmailBody(),( ConfirmationTokens( TokenStorage()))->add( ConfirmationToken( UUID(), TokenStorage(), UUID() // it's a token string)))->send();} public function new new new new new new new new new new new Here is a variation of how an object can be persisted. I use a collection-like class that can be used for adding and searching for tokens. And here is a pretty straightforward implementation: ConfirmationTokens RegistrationForm->composeConfirmationEmail() composeConfirmationEmail(ICanSendEmails $transport,EmailHeader $subject,EmailBody $body,ConfirmationToken $token){ ( ConfirmationEmail($transport,$this-> ->getById($this-> )[ ],$subject,$body,$token))->save();} public function return new storage id 'email_address' And, finally, that’s an entry point for user confirming an email: confirmEmail(UUID $formId, UUID $tokenValue){( RegistrationForm($formId, RegistrationFormDataStorage()))->confirmEmail(( ConfirmationTokens( TokenStorage()))->byValue($tokenValue));} public function new new new new Successful confirmation leads to a registration of a new full-fledged user: confirmEmail(ConfirmationToken $token){ ($this->generatedToken()->confirm($token)) {$data = $this-> ->getById($this-> ); public function if storage id (**new** User( **new** UUID(), **new** UserDataStorage() )) ->register( **new** Name($data\[**'name'**\]), **new** Passport( **new** PassportNumber($data\[**'passport\_number'**\]), **new** PassportIssuedAt($data\[**'passport\_issued\_at'**\]), **new** PassportIssuedWhere($data\[**'passport\_issued\_where'**\]) ), **new** Email($data\[**'email'**\]) ); } } Wrapping it up So with fully discarding data-model and the way objects should be persisted, and concentrating exclusively on behavior, I can come up with a descent model.