5

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 ?

MEM
  • 30,529
  • 42
  • 121
  • 191
  • 1
    I'm sorry but it's very hard to understand what you're asking here. You might want to look at Abstract classes to see if they do what you want. – James C May 04 '11 at 15:40
  • I've added an example that perhaps clarifies the situation. – MEM May 04 '11 at 15:46
  • `Now, let's imagine that the author object has 200 properties or so` - we passing reference to object, not copy. – OZ_ May 04 '11 at 19:58
  • @OZ_ I believe you add an importance issue here. You are saying that we are passing a reference, and we are NOT coping it,so that means, this is, a false question to start with?Passing an object with one property, or an object with 12312312312 properties.It's the same.They both referring to one single reference each, hence the performance argument doesn't run.Is that it?So, the only reason why we may what such thing, is, perhaps, that of mimic our Domain the best we can and, translate, the best we can, business issues, by properly translating then into OOP language.Does this make sense?Thanks. – MEM May 04 '11 at 20:59
  • Also another reason we may want to pass something more specific rather then an object is also because, if we need to maintain this code, or share it with others, it will be easier to detect what, specifically are we working on that method. Are those two last comments, two valid reasons ? – MEM May 04 '11 at 21:03
  • @MEM let me say in short: 1) objects can be passed only by reference. 2) Type hinting is good tool to avoid overhead of verification. 3) it's always better to use Interface for type hinting, than name of concrete class. – OZ_ May 04 '11 at 21:06

3 Answers3

2

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.

hakre
  • 193,403
  • 52
  • 435
  • 836
2

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.

James C
  • 14,047
  • 1
  • 34
  • 43
  • Aside note: And should Exceptions be used on that context ? Shouldn't we moderate their use for real exceptional things ? (I'm just asking because I've hear this a lot). Anyway, and despite that, your method seems to be less heavy (in terms of created files), when we have a few required properties. With the interface suggestion, however, it seems that we have a waste of resources but, more space for future add-ons if possible. An old question hm? ... – MEM May 04 '11 at 15:57
  • 1
    You could throw a [UnexpectedValueException](http://php.net/manual/en/class.unexpectedvalueexception.php), that's one already part of PHP. For Interfaces, you don't need to care about checking for certain properties at all - PHP has already done this for you and would have thrown an exception before it even touched the code of the function body. However regardless what decision you take: each one has cons and pros. You need to decide and then stick to your decision, because afterwards you know better. From what you write I think it's time you start doing something :) – hakre May 04 '11 at 20:18
  • Indeed hakre. I really need to work a little with this, to feel it... and better understand. The same may arrive by theoretically studing it as well, but not on this circumstances. – MEM May 04 '11 at 20:54
2

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.

David Weinraub
  • 14,144
  • 4
  • 42
  • 64
  • Thanks for showing me all those alternatives... I really need to start coding something or I will lose the purpose of all this. ;) Thanks again. :)) – MEM May 04 '11 at 20:52