Is this legal use of the Abstract Factory pattern?

Here is what I am trying to implement in my program:

  • The program should open a zip file containing many data files
  • The format of the data files may vary between zip files (for example, csv, with tab delimiters, or it may even be some kind of binary file that requires decoding)
  • However, in the zip file all data files will be of the same type

I read "Design Patterns" by Gamma et al. And reviewed the Abstract Factory pattern to try to solve this problem.

Ideally, I want to have one class for a Zip file that can read any type of data file inside it. I think I would have two classes - FileTypeA and FileTypeB, which could handle different data formats (although there may be more in the future). I would like to talk about my ZipFile class, what type of file to use when reading data.

So far this is what I came up with:

<?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->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->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<br/>";
    }

    public function setSampleId(){
        echo "Setting sample id of a file A<br/>";
    }
}

/**
 * Concrete class that processes a data file of type 'B'
 */
class FileB extends DataFile{
    public function readData(){
        echo "Reading data from a file B<br/>";
    }

    public function setSampleId(){
        echo "Setting sample id of a file B<br/>";
    }
}

/**
 * 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->files as $fileName){//loop through each file in the zip
            $file = $factory->createFile($this->sampleId);//use the factory to create the desired file
            $file->readData();//now read the data from the file!
            echo "object created of type: ".get_class($file)."<hr/>";
        }
    }
}

/***********************************************************************************************
 * 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->readFiles($factory);//read the files, passing the correct factory object to it

Can someone tell me: (A) Is this a good way to achieve what I'm looking for, or is there some simpler way to do this? (B) Is this actually an abstract Factory pattern, or am I completely misunderstood?

Thanks in advance!

+4
source share
1 answer

, , .

abtract - , , interfaces.

interface IDataFileFactory{
    public function createFile($id);
}

class FileAFactory implements IDataFileFactory
class FileBFactory implements IDataFileFactory

FileAFactory FileBFactory, .

interface IDataFileFactory{
    public function createFile($id);
}

abstract class BaseFileFactory implements IDataFileFactory {

//some methods implementation with common features to avoid repeating code
//some abstract methods to be implemented for A and B FileFactories
//absolute abstract base class has no sense because in php you can use interfaces.
//...
}

class FileAFactory extends BaseFileFactory
class FileBFactory extends BaseFileFactory

throug:

  public function readFiles(IDataFileFactory $factory){
           //create a file using factory
           return IDataFile; //return Interface implemented by all DataFile types.
        }

DataFile ..

, factory . . , , factory.

, , factory ; , , factory. - inyection.

, .

, .

+7

All Articles