Note that there are some explanatory texts on larger screens.

plurals
  1. POIs this a legitimate use of the Abstract Factory pattern?
    primarykey
    data
    text
    <p>Here's what I'm trying to implement in my program:</p> <ul> <li>The program should open a zip file, which contains many data files </li> <li>The format of the data files can differ between zip files (e.g. csv, tab delimited, or could even be some kind of binary file which needs decoding)</li> <li>However, within a zip file all data files will be of the same type</li> </ul> <p>I have been reading "Design Patterns" by Gamma et al., and have been looking at the Abstract Factory pattern to try to solve this.</p> <p>Ideally, I want to have one class for the Zip file, which can read any type of data file within it. I guess I would have two classes - FileTypeA and FileTypeB, which could process different formats of data (although there could be more in the future). I would like a way of telling my ZipFile class which type of file to use when reading the data.</p> <p>So far, this is what I have come up with:</p> <pre><code>&lt;?php /** * An abstract factory used for creating data files of any type */ abstract class DataFileFactory{ abstract function createFile($id); } /** * A factory for creating and setting up a data file of type 'A' */ class FileAFactory extends DataFileFactory{ public function createFile($id){ $file = new FileA(); $file-&gt;setSampleId($id); return $file; } } /** * A factory for creating and setting up a data file of type 'B' */ class FileBFactory extends DataFileFactory{ public function createFile($id){ $file = new FileB(); $file-&gt;setSampleId($id); return $file; } } /** * An abstract class which defines some functionality of a data file */ abstract class DataFile{ abstract function readData(); abstract function setSampleId(); } /** * Concrete class that processes a data file of type 'A' */ class FileA extends DataFile{ public function readData(){ echo "Reading data from a file A&lt;br/&gt;"; } public function setSampleId(){ echo "Setting sample id of a file A&lt;br/&gt;"; } } /** * Concrete class that processes a data file of type 'B' */ class FileB extends DataFile{ public function readData(){ echo "Reading data from a file B&lt;br/&gt;"; } public function setSampleId(){ echo "Setting sample id of a file B&lt;br/&gt;"; } } /** * Concrete class that reads a zip file and reads each file within the zip */ class ZipFile{ private $files = array("file1.txt","file2.txt","file3.txt","file4.txt");//this would be an array read from the zip file private $sampleId = 1;//this would be derived from some other function /** * Read all the files in a zip archive. * $factory can be an instance of any class that extends DataFileFactory, and is used for creating each file */ public function readFiles(DataFileFactory $factory){ foreach($this-&gt;files as $fileName){//loop through each file in the zip $file = $factory-&gt;createFile($this-&gt;sampleId);//use the factory to create the desired file $file-&gt;readData();//now read the data from the file! echo "object created of type: ".get_class($file)."&lt;hr/&gt;"; } } } /*********************************************************************************************** * IMPLEMENTATION ***********************************************************************************************/ $zip = new ZipFile();//create a new zip file $factory = new FileAFactory();//instantiate a new factory, depending on which type of file you want to create $zip-&gt;readFiles($factory);//read the files, passing the correct factory object to it </code></pre> <p>Can anyone tell me: (A) Whether this is a good way of achieving what I'm looking for, or is there some simpler way of doing it? (B) Is this actually the Abstract Factory pattern, or have I completely misunderstood?</p> <p>Thanks in advance!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload