How to represent mandatory business fields on a model structure?
If we use type hinting, we can place an object mandatory:
public function myMethodThatDoFineStuff(MyObject $myobject) {
}
What if, we would like to place, not the all object but only some of it's attributes, to be mandatory ? Let's assume that our domain model will be better, if it better represents a certain domain.If this could开发者_开发技巧 make more sense on our business model (on our domain)? How should we do it ?
Our should we always place the ALL Object no matter what ?
EXAMPLE for clarification proposes:Let's imagine that, in order to list books of a certain author we have this method:
public function listBookOfAuthor(Author $author) {
}
Now, let's imagine that the author object has 200 properties or so, BUT, in order to process the list of books, we only need their first and last name.
Should we receive the ALL $author object anyway ?
I would test for required properties in the following way:
public function listBookOfAuthor(Author $author) {
if (empty($author->firstName)) {
throw new listBookOfAuthorException('firstName must be defined');
}
}
If you find you're doing this lots you could write some kind of parent class that includes a method for checking properties are present.
What if, we would like to place, not the all object but only some of it's attributes, to be mandatory ?
Technically you can create an interface with only those some attributes the function expects. Isolated this might look a bit like overhead but Interfaces are worth to play around a bit with, more in the manual how they work in PHP.
Just because it could make more sense on our business model ?
I know nothing about your business model, so I can't say if it makes sense or not. But I thought you were asking a programming question not a business one.
Our should we always place the ALL Object no matter what ?
Then you'll loose type hinting but you will be able to pass any object. Depends a bit how strict you want to write your code. If you use interfaces you're pretty flexible when refactoring the code (changing concrete object implementations), as well as with the stclass object. However with the stdclass object the function needs to verify what it get's first before processing on the functions input.
Depending upon your schema, the method listBooksOfAuthor()
(which looks like a method on a service object like BookService
) could probably suffice with only an $authorId
, not a full Author
object.
But I think I understand the point of question. Perhaps the Author
object is expensive to fully populate - say, from a method like AuthorService::getAuthorById()
.
For those circumstances when all you need is a modest subset of Author
functionality, then perhaps you could create a distinct interface - maybe something like AuthorSummaryInterface - that reflects only those methods you need for those circumstances. Allow the Author
object to implement that interface so that when you already have an Author
object in hand, you can perform operations that only require that limited Author
functionality. Alternatively, you could create a method Author:getSummary()
that returns a concrete implementation of AuthorSummaryInterface
. In this method, you could enforce your member requirements - must have a name, for exmaple - and throw an exception when those requirements are not fulfilled.
You might also create a set of methods - perhaps on an AuthorService
object or an AuthorSummaryService
object - that produce AuthorSummary
objects. Then in those circumstances where only AuthorSummaryInterface
functionality is required, you can create these limited functionality, less-expensive-to-create objects.
Just some ideas.
精彩评论