views:

100

answers:

2

Background

I need to design a set of utility classes that will ease out file system access to several types of remote services (Local, FTP, WebDAV, SVN, SSH), and I cannot seem to get a "perfect" design mostly because of a language barrier - I feel that every design path I have chosen was scraped because PHP did not have support for a specific feature.

I find this frustrating and I'm out of ideas.

Requirements

A base abstract class or interface for FileSystem which every other file system type inherits. The FileSystem class (and it's subclasses) are a 'driver' that implement basic FS operations such as 'move', 'remove', 'create' and so on.

Those driver operations should not be exposed to the class user, instead, FileSystem is also a factory that fetches file info records upon request.

A file is also based on an abstract class or interface File and Directory, which the implementors of a FileSystem subclass may or may not subclass. Users of a FileSystem class do not 'care' about the type of a File (SshFile and SvnFile should work the same).

The File (and Directory) class should be the one to talk to the file system driver that created it in some way without the user being able to do it manually through the FileSystem driver.

What I have tried

Naturally I made FileSystem an abstract class, then proceeded to code the class File and turns out that PHP has no friend support, so File cannot have access to FileSystem's protected driver methods.

Another idea that got scraped was a class inside a class - FileSystem and FileSystem::File - PHP does not have nested classes.

Divide FileSystem into FileSystemDriver and FileSystemFactory, but that gets me into the same original problem.

300 Reputation points in bounty reward

To a solver of an original idea to PHP's lack of programming utilities needed for encapsulation.

A: 

Why can't you separate FileSystemDriver from FileSystem? For example:

class SSHFileSystem {   
    private $driver = new SSHDriver();

    function getFile($path)
    {
     return new SSHFile($this->driver, $path);
    }
}
Tom Dalling
Because the user might instantiate `SSHDriver`. I do not want it used. `File` should be the programmer's interface, not the file system/driver.
LiraNuna
I see. In my experience with PHP, the only way around that is to document the class with something like "_this class is private, use class XYZ_". You just have to hope that the other developers follow the documentation.
Tom Dalling
A: 

Documentation problem, not code problem.

Leave the FileSystem's methods as public but document that they should only be used by internal File and Directory objects.

This is very common in languages. Python has magic methods, or the _function notation, etc.

If I'm a user, I don't just look at every available method and start using it if it sounds fun, I read the docs and do what they say.

Paul Tarjan
Ignoring (or documenting) the problem won't make it go away, unfortunately.
LiraNuna
It's not actually a problem until someone gets in and abuses the private classes. If you're trying to force bad programmers to be good, then you're fighting a battle you can't win.
Tom Dalling