On Wed, Jun 3, 2009 at 2:34 PM, Matthew Weier O'Phinney <[email protected]> wrote: > -- Andrew Ballard <[email protected]> wrote > (on Wednesday, 03 June 2009, 09:47 AM -0400): >> I have been looking over the data mapper pattern used in the current >> Quickstart. I like the separation of the data model from the storage, >> but I have a question. >> >> In the guestbook model, setId() and setCreated() are declared public. >> I realize this is necessary in the example because the values are >> being set by the mapper, which is external to the domain model class. >> However, I would think that it would be desirable some properties such >> as these one to be generally read-only. Is there any way to control >> which external classes are able to use these methods? Java has a >> package scope that would work, but PHP doesn't even have a concept of >> packages in its OO implementation. > > PHP doesn't have such a concept. One way to get around it is to only > allow setting of particular properties by passing them to the > constructor, which is a technique I've often seen. > > -- > Matthew Weier O'Phinney > Project Lead | [email protected] > Zend Framework | http://framework.zend.com/ >
I know the concept of friend/package scope doesn't exist in PHP. From a purely theoretical OO perspective, maybe it should not exist in any language: When you want to modify an object from outside, you should communicate directly with one of its public interfaces. Still, when making the leap from the theoretical to the practical, it seems that often you need a way of allowing SOME external objects to access methods that most other external objects cannot. I've tried the technique you mentioned before (not related to this data mapper model). It doesn't completely lock things down, but it seems to be a step in the right direction. The example project is already built to do this by accepting an array that it hands off to setOptions(), which will load any properties whose name matches a setter method in the class. What about an approach that extends that idea somewhat by adding a way to trigger the domain model (for instance, in its constructor, its setMapper method, or perhaps a new load() method) to call a special getMappedData() method in the mapper that would return a structured set of properties (an array, stdClass, etc.). The model would then process the data returned from the mapper to initialize its own properties. This way the model keeps the responsibility for setting its own properties by accessing data from a class that it trusts. It seems to me that this drastically restricts the ability for an external class to inject anything. My concern is that the model and the mapper then become tightly coupled. Would having the mapper implement a Zend_DataMapper_Interface be sufficient to decouple them? Would the risk that another class could easily impersonate a trusted data mapper by implementing the interface nullify any benefit gained? Andrew
