SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 60
  1. #1
    SitePoint Zealot
    Join Date
    Oct 2004
    Location
    naperville
    Posts
    189
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How useful is a Dataspace?

    What are the pros and cons of a dataspace (think the skeleton threads)? My initial gut reaction tells me its unnescesarry, but the wide spread use indicates I'm missing something. PHP5, if it matters.

    What should a dataspace do?

    Quote Originally Posted by selkirk
    Rephrasing the questions that began this thread:

    What are the pros and cons of a property? What should a property do?

    What are the pros and cons of a component? What should a component do?

    What are the pros and cons of creating an OO interface for non-oo data? What should such an interface do?
    Last edited by Super Phil; Jan 9, 2006 at 23:37.

  2. #2
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Super Phil
    What should a dataspace do?
    Contain stuff. Allow it to be handled in a flexible manner. Allow itself to be decorated. Allow itself to be extended from (think of a Dataspace that loads itself from a configuration file). They are useful. I like the name Container more, though. It's simple and to the point.

  3. #3
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)


    PHP Code:
    interface IDataspace {
            public function 
    set();
            public function 
    get();
            public function 
    has();
        }
        
        abstract class 
    Dataspace implements IDataspace {
            protected 
    $parameters = array();
            
            public function 
    __construct() {}
            public function 
    set() {
                
    $parameters func_get_args();
                if( 
    is_array$parameters ) ) {
                    
    $this -> parameters[strtolowerarray_shift$parameters ) )] = array_shift$parameters );
                }
            }
            
            public function 
    get() {
                
    $parameters func_get_args();
                if( 
    is_array$parameters ) ) {
                    if( 
    array_key_exists$parameter array_shift$parameters ), $this -> parameters ) ) {
                        return 
    $this -> parameters[$parameter];
                    }
                }
                return 
    false;
            }
            
            public function 
    has() {
                
    $parameters func_get_args();
                if( 
    is_array$parameters ) ) {
                    if( 
    array_key_exists$parameter array_shift$parameters ), $this -> parameters ) && !empty( $this -> parameters[$parameter] ) ) {
                        return 
    true;
                    }
                }
                return 
    false;
            }
            
            public function 
    importIDataspace $dataspace ) {
    // commented out following, use the replacement below
    // array_merge( $this -> parameters, $dataspace -> export() ); // old

    // replacement...
    $this -> parameters array_merge$this -> parameters$dataspace -> export() ); // new
            
    }
            
            public function 
    export() {
                return 
    $this -> parameters;
            }
        } 
    But I would say that it has to be minimalistic as well
    Last edited by Dr Livingston; Feb 25, 2006 at 12:40. Reason: fix a bug...

  4. #4
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I agree with what Ezku and Dr Livingston said, I just have a small comment about import() and export() methods Dr Livingston introduces in his code. In a way, I feel import should be an inverse function of export, so either both should operate on array or both should operate on IDataspace. I usually use arrays with these and provide another method such as copyFrom(IDataspace $ds) (or copyTo) for importing data from another IDataspace.

  5. #5
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Super Phil
    What are the pros and cons of a dataspace (think the skeleton threads)? My initial gut reaction tells me its unnescesarry, but the wide spread use indicates I'm missing something. PHP5, if it matters.

    What should a dataspace do?
    DataSpace is really just a standard Container for use by PHP apps. The long thread here discussed the Keyed implementation in detail. A standard Container, like the DataSpace implementation, is one of the best things that I have found in PHP to clean up frameworks. The magic is that so many things can be implemented as a Keyed Container: Request, Response, Service Locator, Session, Config, Template, DB RecordSet, etc. This provides opporunities for code reuse (DRY) and interesting new things that you can do because things share the same interface.

    Dr Livingston shows what I consider the cleanest current PHP implementation. Things may change with PHP6 regarding property support, but I think the straightforward implementation above is best right now. It many people and frameworks standardized on it we would all be better off in my opinion because of the interoperablity that would occur.
    Christopher

  6. #6
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For comparison, I use something along the lines of this.
    PHP Code:
    class Container implements IteratorArrayAccess
    {
        
    /**
         * @var    array    container data storage
         */
        
    private $__data = array();
        
        
    /**
         * @param    string    resource name
         * @return    mixed    reference to a resource, NULL if not found
         */
        
    public function & get($name)
        {
            
    $retval NULL;
            if (isset(
    $this->__data[$name]))
            {
                
    $retval =& $this->__data[$name];
            }
            return 
    $retval;
        }
        
        
    /**
         * @param    string    resource name
         * @param    mixed    resource
         * @return    void
         */
        
    public function set($name$value)
        {
            
    $this->__data[$name] = $value;
            return 
    $value;
        }
        
        
    /**
         * @param    string    resource name
         * @return    boolean
         */
        
    public function has($name)
        {
            return isset(
    $this->__data[$name]);
        }
        
        
    /**
         * @param    string    resource name
         * @return    mixed    resource value prior to removal, NULL if not found
         */
        
    public function remove($name)
        {
            
    $retval NULL;
            if (isset(
    $this->__data[$name]))
            {
                
    $retval $this->__data[$name];
                unset(
    $this->__data[$name]);
            }
            return 
    $retval;
        }
        
        
    /**
         * Retrieve list of contained resources
         * @return    array
         */
        
    public function names()
        {
            return 
    array_keys($this->__data);
        }
        
        
    /**
         * Fetch contained resources to an array
         * @return    array
         */
        
    public function to_array()
        {
            return 
    $this->__data;
        }
        
        
    /**
         * Pick values from Container
         * @param    array    list of picked value names, or alternatively a transform table (from => to)
         * @return    array
         */
        
    public function pick($keys = array())
        {
            
    $retval = array();
            foreach(
    $keys as $to => $from)
            {
                
    $to is_int($to) ? $from $to;
                
    $retval[$to] = $source[$from];
            }
            return 
    $retval;
        }
        
        
    /**
         * Merge current data with that from another array or Container
         * @param    mixed    array or Container
         * @return    boolean    false on failed merge
         */
        
    public function merge($data)
        {
            switch (
    true)
            {
                case (
    $data instanceof self):
                    
    $data $data->to_array();
                case (
    is_array($data)):
                    
    $this->__data array_merge($this->__data$data);
                    return 
    true;
                default:
                    return 
    false;
            }
        }
        
        
    /**
         * Container constructor. Pass a mergeable argument to set initial values.
         * @param    mixed    initial values, optional
         */
        
    public function __construct($data NULL)
        {
            
    $this->merge($data);
        }
        
        public function 
    __set($name$value) { return $this->set($name$value); }
        public function & 
    __get($name) { $val =& $this->get($name); return $val; }
        
        
    // Implement Iterator
        
    public function current() { return current($this->__data); }
        public function 
    key() { return key($this->__data); }
        public function 
    next() { return next($this->__data); }
        public function 
    rewind() { return reset($this->__data); }
        public function 
    valid() { return current($this->__data) !== FALSE; }
        
        
    // Implement ArrayAccess
        
    public function offsetExists($offset) { return isset($this->__data[$offset]); }
        public function 
    offsetSet($offset$value) { return $this->set($offset$value); }
        public function 
    offsetGet($offset) { return $this->get($offset); }
        public function 
    offsetUnset($offset) { unset($this->__data[$offset]); }


  7. #7
    SitePoint Enthusiast
    Join Date
    Dec 2005
    Posts
    29
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
     $parameters func_get_args();
                if( 
    is_array$parameters ) ) { 
    Is always true.

  8. #8
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is there any reason why the PHP5 implementations of DataSpace don't inherit from ArrayObject ?

  9. #9
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is always true.
    That is true, so you can easily live without it, and remove the condition check, but I decided just to leave it in there; I have my reasons of course

  10. #10
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ren
    Is there any reason why the PHP5 implementations of DataSpace don't inherit from ArrayObject ?
    I would say the basic Container should not implement arrays because only some of the derived containers need it. You could certainly do a KeyedIteratable interface that would be an extension of Keyed. Ezku's Container is getting a little too kitchen-sinky for my tastes.
    Christopher

  11. #11
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ren
    Is there any reason why the PHP5 implementations of DataSpace don't inherit from ArrayObject ?
    Well, yes. While it may, when convenient, be seen as a decorated array, I don't consider Container to be an object of equal semantics. Namely, ArrayObject seems to have 2 irrelevant methods: append and getIterator. Perhaps it's just my about limited perception, though. In the words of arborint, as I remember, "I do like the challenge of convincing Ezku otherwise."

  12. #12
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    Well, yes. While it may, when convenient, be seen as a decorated array, I don't consider Container to be an object of equal semantics. Namely, ArrayObject seems to have 2 irrelevant methods: append and getIterator. Perhaps it's just my about limited perception, though. In the words of arborint, as I remember, "I do like the challenge of convincing Ezku otherwise."
    Yes, append() doesn't quite fit the scenario, getIterator() is just an implementation detail I think, its either implement Iterator, or IteratorAggregate to get foreach() etc working and SPL has picked the latter.

  13. #13
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Think of a dataspace as a pattern for objects to declare properties with accessor methods and a standard interface for accessing the properties of an object. Properties form the data access facet of a component model.

    Betrand Meyer (Object-oriented software construction, p 57) offers the "Uniform Access Principle:"
    All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.
    The intent of this pattern is to comply with the UAP in PHP.

    Compare to C# properties, Java Beans (chapter 7), Objective C Key Value Coding, Ruby Attributes, Python Properties, Delphi Properties.

    PHP is sadly deficient in this area compared to the languages it competes against.

    I think I coined the term DataSpace in WACT. Its a terrible name and my understanding of this pattern has evolved much since then. I now prefer to say that a class implements the Properties interface, or implements the properties pattern. This means that an object implements a uniform notation for accessing data members which hides whether that data member is implemented via storage or computation.

    There is an orthogonal issue as well. Sometimes it can be useful to bind to a component using an expression. You see this pattern repeated in the JSTL expression language, cocoa bindings, .Net data binding expressions and OGNL. Early in WACT the implementation of the UAP and the implementation of binding were coupled in the DataSpace class.

    After the long and useful interface standards thread, I've come to see UAP support and binding support as separate concerns.

    I dislike the name container because I think that name focuses too much on one possible implementation, and less on the intent.

    I also dislike the name Keyed because I think that name focuses too much on the binding aspect.

    Properties, Properties, Properties.

  14. #14
    SitePoint Enthusiast
    Join Date
    Dec 2005
    Posts
    29
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So if I'm interpreting this correctly, you're suggesting that all classes should extend or implement the IDataSpace (or Properties) class for php5's magic funcs to implement (or something).

    This would then make it seem more like what has been reffered to elsewhere as the common object.

    Also, wouldn't the defined constant 'WACT_ROOT' then break this principle ? For example, suppose I have an application that wanted to be made available in the wact framework, my registry's (config) datasource would then have to figure out whether WACT_ROOT is in the main wact dataspace (config) or is a predefined constant but this seems like that should be the responsibility should the wact dataspace/datasource/config object, e.g $$wact->get('WACT_ROOT') ?

  15. #15
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk
    I think I coined the term DataSpace in WACT. Its a terrible name and my understanding of this pattern has evolved much since then. I now prefer to say that a class implements the Properties interface, or implements the properties pattern. This means that an object implements a uniform notation for accessing data members which hides whether that data member is implemented via storage or computation.
    ...

    I dislike the name container because I think that name focuses too much on one possible implementation, and less on the intent.

    I also dislike the name Keyed because I think that name focuses too much on the binding aspect.

    Properties, Properties, Properties.
    I think Properties and Keyed are two different solutions to the same problem, not the same thing. Properties is definitely object-y, whereas Keyed is definitely string-y. The question of which one to use depends a little on style. PHP code certainly has centered around associative arrays and string keys for a long time. PHP's arrays are one of it's defining features. They have that "just work like I expect it to" quality that makes scripting in PHP what it is (compare to Perl's "is it an array or a hash?").

    There is a fundamental difference between $obj->name = $value and $obj->setname($value) and $obj->set('name', $value) that transcends functionality (because they do the same thing) and is about style and whether the things that the object deals with are other objects or arrays. Something like C# getters and setters would change things. But when we have things like $obj->$name = $value vs $obj->set$name($value) vs $obj->set($name, $value) I tend to resort to the last because it seem clearer in PHP.
    Christopher

  16. #16
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm curious, but what do you guys consider to be the difference between a DataSpace/Container/Whathaveyou and a Model? That the latter is persistable? Or that it has methods to manipulate the data?

  17. #17
    SitePoint Zealot
    Join Date
    Oct 2004
    Location
    naperville
    Posts
    189
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What about some people who oppose it; ie, those who think that using class members and arrays is generally enough? (I'm not sure who this is, if anyone - marcus or mcgruff, do you guys have different opinions?). It's hard to make an educated opinion with just supporters.

    33deg - as I understand it, dataspace's are purely for holding data. There would be no business logic, so its not a model (right?)

    Is a dataspace + iterator a likely (the likely) use scenario? To play devils advocate, does it really have benfits past an array? I mean, arrays are reusable, etc

  18. #18
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think the benefit of a DataSpace is that it's an interface, thus it could be just an objectified array, but it might also be something more complex (such as a domainmodel object)

  19. #19
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk
    I dislike the name container because I think that name focuses too much on one possible implementation, and less on the intent.

    Properties, Properties, Properties.
    You're right, Properties is a nice generalization. In my case, Container describes both the intent and the implementation. Semantics, semantics, semantics.

  20. #20
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    I think the benefit of a DataSpace is that it's an interface, thus it could be just an objectified array, but it might also be something more complex (such as a domainmodel object)
    This is exactly it. The interface it the important thing. Once you settle on some solid interfaces then many things start to fall into place because you gain flexiblity.

    An example I can think of is the Response. It can be as simple as a straight PHP page, or as complex as a tree of Response Children each with Views that contain Templates. I have found that if Templates, Views and Response Children all implement DataSpace plus a render function then I can have as complex or as simple a Response as is needed by the page.
    Christopher

  21. #21
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Once you settle on some solid interfaces then many things start to fall into place because you gain flexiblity.
    Maybe, but I tend to look at it, that once you have an Interface that has settled down, you can be more confident on how you allow your application development to continue with those Interfaces with minimal interferance...

    Interferance that would be there without the functionality of Interfaces that PHP5 introduces to us.

  22. #22
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Selkirk
    I dislike the name container because I think that name focuses too much on one possible implementation, and less on the intent.

    I also dislike the name Keyed because I think that name focuses too much on the binding aspect.
    OK, you've lost me. What is the difference here between the (illusion of a) container and binding? In fact, what do you mean by "binding"? As I don't use either Cocoa or .NET, I'm kinda' lost right now.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  23. #23
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by devosc
    This would then make it seem more like what has been reffered to elsewhere as the common object.
    I doubt that is what is meant. There are a lot of classes that don't have any visible properties. In fact most classes should be like this. This interface is for when the OO paradigm brushes up against things in the outside world that don't want to play ball. Requests, database rows, etc.

    Of course if PHP has overloading of the [] accessor, all of this properties stuff would disappear.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  24. #24
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by 33degrees
    I'm curious, but what do you guys consider to be the difference between a DataSpace/Container/Whathaveyou and a Model? That the latter is persistable? Or that it has methods to manipulate the data?
    What do you mean by Model? If you mean the "M" in MVC, then there is no reason for the model to be persistable. In fact model is defined in this context by what it is not. It's not the "C" (mouse clicks) and it's not the "V" (pixels). The "model" of a search engine would not contain persistence at it's core.

    If you mean "domain model" or "business logic", again some of it may be persistent and some may not. You try to make it pure OO though, and reserve these types of interface for infrastructure stuff.

    If you mean the "data model", then yeah, you'd have a common class that wouldn't really be a free and easy class, more of a direct mapping to the underlying system.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  25. #25
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    This interface is for when the OO paradigm brushes up against things in the outside world that don't want to play ball. Requests, database rows, etc.
    That's really the key utility of it and the magic of its use in PHP.

    Quote Originally Posted by lastcraft
    Of course if PHP has overloading of the [] accessor, all of this properties stuff would disappear.
    Shhhhhhhhh .... if you start blabbing excellent ideas they will never happen !
    Christopher


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •