Я написал несколько уроков и пришел на развилку в дороге по поводу того, что мне следует делать. Мой базовый вопрос: как избежать дублирования кода между классами с очень похожей функциональностью? Черты для меня сейчас не вариант, и я не думаю, что они все равно будут здесь сильно помогать.
У меня реализованы следующие классы.
//either a directory or a file on the file system
class FileSystem_Object{
//the size of the class in bytes
public function getSize(){}
//same as phps native realpath
public function getRealPath(){}
}
//a zip file on the file system, e.g. files that end in .zip extension.
class FileSystem_Object_Zip extends FileSystem_Object{
//returns size of all files if they were to be uncompressed, in bytes
public function getUncompressedSize(){}
}
//a singleton file that keeps track of only one object copy of a file
class FileSystem_Manager{}
Эти классы sortof предоставляют мне некоторые функциональные возможности типа SPLFileObject. Я могу делать следующие вещи
$object =
FileSystem_Manager::getInstance()
->getFileSystemObjecT( '/some/path/to/file/or/directory/' );
Каждый раз, когда я вызываю метод getFileSystemObject, он либо возвращает новый объект класса, либо возвращает объект, уже назначенный этому пути, что позволяет избежать создания нескольких объектов, указывающих на один и тот же путь в файловой системе. (возможно, не самая лучшая идея, но это то, что я пошел с.)
Здесь мы немного подойдем к вопросу.
У меня есть другой набор классов, которые я использую для «блокировки» объектов. Прямо сейчас единственные объекты, которые я блокирую, это filesystem_objects, независимо от того, являются ли они каталогами или файлами. Это работает достаточно просто путем создания файла блокировки для файла на основе идентификатора процесса php-процесса, пытающегося его заблокировать.
inteface Lockable_Object{
public functon getLockableIdentifier();
}
class Lockable_FileSystemObject implements Lockable_Object{
/**
* I return a false here if the file doesn't exist
* so any other processes trying to lock this file will
* know they can no longer lock it because it has moved
* or been renamed for some reason.
*/
public functon getLockableIdentifier(){
if( file_exists( $this->_fullFilePath ) ){
return $this->getRealPath();
}
return false;
}
}
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я хотел бы создать объект Zip-файла, который также может быть заблокирован, и я хотел бы иметь возможность блокировать практически любой файл / каталог, но я НЕ хочу должен дублировать код. Что из следующего я должен сделать
//Option 1
class Lockable_Object_Zip extends FileSystem_Object_Zip
implements Lockable_Object{
//In here I would have to duplicate the getLockableIdentifier method and do that
//for every file type i decide to make in the future
}
//Option 2
class Lockable_Object_Zip extends Lockable_FileSystemObject
//In here I would have to duplicate all the zip functionality coded into
//FileSystem_Object_Zip
}
//Option 3
class FileSystem_Object implements Lockable_Object{
//build in the 'lockablity' into the base class
}
Прямо сейчас я склоняюсь к варианту 3, но единственная причина, по которой я не хотел бы этого делать, - это то, что тогда у меня должна была бы быть часть «Locker» моей библиотеки всякий раз, когда я хочу использовать материал файловой системы; это было бы более тесно связано.
Я уверен, что у вас будут комментарии о дизайне, и некоторые скажут: «SplFileObject делает все / большую часть этого». Я включил сюда методы для примеров, и не все методы, которые я реализовал, здесь, так что это не единственная функциональность, которую я написал. Все эти комментарии и многое другое приветствуются, потому что они могут привести меня к дизайну, который позволит избежать всей этой проблемы.
Спасибо