【问题标题】:Create a Collection of Objects from a Class Using a Transformer Function使用 Transformer 函数从类中创建对象集合
【发布时间】:2014-09-02 08:57:03
【问题描述】:

在这个问题中,我想讨论一个与使用转换传递的数组或其他类型的集合的转换函数从类构建同质对象集合相关的问题。问题在于,我希望在进行转换时能够从哪个类中查看集合中的对象,同时避免使用静态,因为我们都知道它们有点棘手,一般建议是避开他们。

场景如下:

  • 有一个抽象类,可以对数据进行一些常见的解析(格式化日期、字符串、浮点数等),称为AbstractData。它的目的是通过更具体的类进行扩展,这些类利用抽象函数并保存解析的数据。
  • 具体类使用映射数组,该数组告诉如何使用抽象类中的函数解析给定的原始数据。

目前创建此类具体类对象的集合的操作如下(注意具体类的构造函数采用单行数据,它使用定义的映射方案自动解析):

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 来解决问题,但我不确定我能做什么。

【问题讨论】:

  • ".. 尽可能干净的代码 .." 这将很大程度上基于意见。可能将其改写为“_____风格与_____风格的优缺点是什么”可能不太基于意见,但就您目前的问题而言,它主要是基于意见的。

标签: php collections dependency-injection static factory


【解决方案1】:

我看不出使用后期静态绑定函数有什么害处任务。我认为您正在尝试根据您静态给工​​厂的类来获取一组项目?这是我解决我认为您要问的问题的技巧。为此,我始终在抽象类上使用公共方法,并在您正在构建的类上定义受保护的方法,因为它们中的每一个都可能以不同的方式处理输入。

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); 

【讨论】:

  • 是的,目前我做的事情和你完全一样,但是有人告诉我这不是一个很好的做法,因为将来引入另一个集合/具体类时可能会导致问题。
  • Static 将始终绑定在它被调用的级别,这就是为什么我存储一个获取类名的静态函数,所以如果我以后扩展它们,我可以管理差异。
  • 我想你误解了我的评论,我的意思是不应该使用静态类/方法(不是后期和早期与 self/static 绑定)。所以我认为这里的问题是我们正在尝试创建一个包含同质对象的集合,这些对象是从对象本身实例化的,这不是一个好习惯。我想创建一个集合类并作为第一个参数传递给它的构造函数 ConcreteClass::class 然后是数据要好得多,这样我们就可以在 PHP 中使用泛型
猜你喜欢
  • 2020-06-21
  • 2011-07-12
  • 2017-01-21
  • 1970-01-01
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多