简体   繁体   中英

PHP classes: abstract, traits, extend, interface, singletons

I had a very long "Playlist" class; having functions that, among others, would handle the playlist cache, variables, and presets.

class Playlist{

    var $cache;
    var $variables;
    var $preset;

    function __construct(){
        $this->cache = populate_cache();
        $this->variables = $this->populate_variables();
        $this->preset = $this->populate_preset();
    }
    function populate_cache(){
    }
    function populate_variables(){
    }
    function populate_preset(){
    }
}

As it was becoming very difficult to read (lots of function for stuff related to cache, variables, presets), I started to split that into several classes (code is reduced here):

class Playlist{

    var $cache;
    var $variables;
    var $presets;

    function __construct(){
        $this->cache = new PlaylistCache($this);
        $this->variables = new PlaylistVariables($this);
        $this->presets = new PlaylistPreset($this);
    }
}

class PlaylistCache{
    var $playlist;
    function __construct(&$playlist){
        $this->playlist = $playlist;
    }
}

class PlaylistVariables{
    var $playlist;
    function __construct(&$playlist){
        $this->playlist = $playlist;
    }
}

class PlaylistPreset{
    var $playlist;
    function __construct(&$playlist){
        $this->playlist = $playlist;
    }
}

So the Playlist object is passed to every "subclass". If I well understood, this is called Dependency Injection . I'm not sure this is very smart since

  • It seems to me quite a weird way of coding.
  • It produces recursions in my code, eg. the playlist object is passed to the PlaylistCache class; but the PlaylistCache IS defined in the playlist object, which makes ... a nasty loop. If I print_r my Playlist object, i'll see RECURSION written in the code.

BUT I need to be able to access the whole Playlist object through every subclass, and that's the only way I found for the moment.

I already know about extending classes , but I don't want to extend my class here : cache, variables and presets are not a different kind of Playlist, they are "properties" that my Playlist needs to populate.

I dug a little and read about Abstract Classes , Traits , Interfaces , and i guess my solution is somewhere in that. But I can't find where and it's quite difficult for me to understand since it's really abstract and english is not my first language.

So : does anyone see what I mean and have suggestions ? Thanks !

Some of the comments are misleading. The "child" classes use Dependency Injection and not an Inheritance parent/child relationship. The playlist (parent) class does use composition, however.

The &'s in the constructors constitute ' passing by reference '. To pass by value, the class would need accessor methods . If you only ever want one instance of say... the current playlist, a singleton makes sense. Traits are a copy paste solution - the design for a singleton pattern could be housed in a trait, but the use of a singleton would not be.

Consider what the playlist* classes actually need from the Playlist and consider passing those values explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM