gpt4 book ai didi

php - 这是对抽象工厂模式的合法使用吗?

转载 作者:可可西里 更新时间:2023-10-31 22:12:03 26 4
gpt4 key购买 nike

这是我试图在我的程序中实现的内容:

  • 程序应该打开一个 zip 文件,其中包含许多数据文件
  • 数据文件的格式可能因 zip 文件而异(例如,csv、制表符分隔,甚至可能是某种需要解码的二进制文件)
  • 但是,在一个 zip 文件中,所有数据文件都是同一类型

我一直在阅读 Gamma 等人的“设计模式”,并且一直在研究抽象工厂模式来尝试解决这个问题。

理想情况下,我希望 Zip 文件有一个类,它可以读取其中的任何类型的数据文件。我想我会有两个类——FileTypeA 和 FileTypeB,它们可以处理不同格式的数据(尽管将来可能会有更多)。我想要一种方法来告诉我的 ZipFile 类在读取数据时使用哪种类型的文件。

到目前为止,这是我想出的:

<?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

谁能告诉我:(A) 这是否是实现我正在寻找的目标的好方法,或者是否有一些更简单的方法来实现?(B) 这实际上是抽象工厂模式,还是我完全误解了?

提前致谢!

最佳答案

这是一个很好的实现,但如果您使用接口(interface),它可以稍微调整一下。

一个带有所有虚方法的抽象类它只是一个接口(interface)所以不要使用抽象类,使用interfaces .

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

class FileAFactory implements IDataFileFactory
class FileBFactory implements IDataFileFactory

如果您在 FileAFactoryFileBFactory 方法中发现重复代码,那么是时候重构您的类并创建继承了。

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

然后通过接口(interface)使用:

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

您可以对 DataFile 基类等做同样的事情。

我还建议不要在参数中传递工厂,因为工厂脱离了上下文。尽量不要将架构实现与数据和信息处理工作流程混合在一起。您可以在其他类可访问的范围内创建一个容器来解析工厂。

例如,容器可以读取配置文件以在应用程序 Bootstrap 中创建具体工厂;从某个值中读取,由用户在用户案例的前面步骤中选择,存储在类实例中或在运行时接受参数以解析工厂。它是关于实现某种简单的依赖项 inyection。

无论如何,这只是我的观点,可能会有大量分歧。

希望对你有帮助。

关于php - 这是对抽象工厂模式的合法使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20224318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com