在这个问题中,我想讨论一个与使用转换传递的数组或其他类型集合的变换器函数从类构建同类对象集合相关的问题。问题在于我希望能够在进行转换时看到集合中的对象是哪个类,同时避免使用静态,因为我们都知道它们有点棘手,一般的建议是避免它们。
方案如下:
AbstractData
数据进行一些常见的数据解析(格式化日期,字符串,浮点数等)。它的目的是通过更具体的类来扩展,这些类使用抽象函数并保存解析数据。目前,创建此类具体类对象集合的工作如下(请注意,Concrete类的构造函数采用单行数据,并使用定义的映射方案自动解析):
collection = [];
foreach($rows as $row) {
collection = new ConcreteClass($row);
}
我在这里基本上只是这些对象的数组,但我想知道保留更结构化集合的最佳方法是什么,就像使用Java中的泛型一样List<ConcreteClass> collection = new List<ConcreteClass>(row);
现在我所做的是在抽象类中创建一个静态的“工厂”函数:
public static function factory($data = null) {
return new static($data);
}
创建“已处理”集合的函数:
public function createCollectionFromRawData($rows) {
$collection = [];
foreach($rows as $row) {
$collection[] = new static($row);
}
return $collection;
}
并调用具体类:ConcreteClass::factory()->createCollectionFromRawData($rows)
虽然它允许以某种方式更好地读取它有点多余,因为它没有分离关注点,另外我必须创建一个ConcreteClass的空对象,只是为了能够调用非静态createCollectionFromRawData函数,我我想避免这样做。
我正在思考涉及DI的问题,以解决问题,但我不确定我到底能做些什么。
答案 0 :(得分:0)
我没有看到使用后期静态绑定函数的危害我在我编写的ORM中大量使用它们但是我确实在每个级别的类中记录了类名,因为我需要一些任务。我想你正试图获得一系列物品,这些物品取决于你静静地给工厂上课的内容?这是我解决我认为你问的问题。我这样做是因为总是在抽象类上使用public方法,并在你正在构建的类上定义受保护的方法,因为每个方法都可能以不同的方式处理输入。
abstract class AbstractData {
protected $_abstractClassData;
public static final function factory($rawData)
{
return static::_createCollectionFromRawData($rawData);
}
}
class ConcreteClass extends AbstractData {
protected $_concreteClassData;
protected static function _createCollectionFromRawData($rows) {
$collection = array();
foreach($rows as $row) {
$collection[] = new static($row); //If you havnt defined a constructor on this class it will use your AbstractData one.
}
return $collection;
}
}
$collection = ConcreteClass::factory($rawData);