如何根据某些标准确定要实例化的父类的哪个子类?

时间:2012-12-09 12:26:02

标签: php

我将尽可能深入地解释我对班级模型的看法(希望)为潜在答案提供更好的基础。

我已经构建了一个类来解析来自应用程序的数据,该应用程序共享在txt文件或html文件中呈现的公共布局,但具有动态数据。我决定尝试用数据处理程序继承解析器类的模型构建它。

解析器类解析导出的数据并创建一个多维$this->parsed数组。然后,子类必须处理数据,在某些情况下,数据类似但布局不同,其他类继承子类。这方面的一个例子是1)雇员名单2)一名雇员的详细视图。在这种情况下,子类Employee包含处理数据的多维数组,并且具有计算年龄等常用方法。由于导出的数据将以不同方式布局(在案例1中列出了几个员工,案例2只有一名员工),我又写了两个班。

这可能是员工列表的$this->parsed数据数组

$parsed[0][0] = Name
$parsed[0][1] = D.O.B.
$parsed[0][2] = E-mail address
$parsed[0][3] = Department
$parsed[1][0] = John Smith
$parsed[1][1] = 1980-3-5
$parsed[1][2] = john@smith.com
$parsed[1][3] = Economics
$parsed[2][0] = Jane Smith
$parsed[2][1] = 1964-1-12
$parsed[2][2] = jane@smith.com
$parsed[2][3] = PR

详细查看员工的$this->parsed数据

$parsed[0][0] = Name
$parsed[0][1] = John Smith
$parsed[1][0] = D.O.B.
$parsed[1][1] = 1980-3-5
$parsed[2][0] = E-mail address
$parsed[2][1] = john@smith.com
$parsed[3][0] = Department
$parsed[3][1] = Economics

由于数据类似,我有一个扩展Parser类的Employee类

abstract class Employee extends Parser {

    $handledData = array();

    abstract public function Populate();

    public function CalculateAge($employeePointer = 0) {

        $dob = $this->handledData[$employeePointer]['dob'];
        // Calculate...

    }

}

由于解析后的数据布局不同,我使用了两个以不同方式读取$this->parsed数组的子类,并将数据设置为$ handlingData

class EmployeeListView extends Employee {

    public function Populate() {

        array_shift($this->parsed); // Remove the "header row"

        foreach ($this->parsed as $employeeArray) {

            list($name, $dob, $email, $dep) = $employeeArray;
            $this->handledData[] = array('name' => $name, 'dob' => $dob, 'email' => $email, 'dep' => $dep);

        }

    }

}

我在详细视图中使用了类似的过程,但我认为这个想法很明确,所以我不会写一个例子。

我偶然发现了使用此布局的问题。由于导出的数据是动态的,因此它将以多种形式出现。虽然不是无限的,但变化量可能高达100,如果不是更多的话。现在,在这两个类中,我编写了Validate()方法,这些方法递归地获取$this->parsed数组的大小并检查其内容以验证数据应该由该类处理。只要我明确知道要使用哪个类,那就行得很好。但是,我希望我的用户能够将文件上传到解析器,而无需花时间滚动浏览大量潜在的处理程序类,以找出适合他们上传文件的文件。

如何动态选择要使用的子类?我可能会做这样的事情:

$buffer = file_get_contents($uploadedFile);
$classes = array('EmployeeListView', 'EmployeeDetailView');
foreach ($classes as $className) {
    $loadedClass = new $className();
    $loadedClass->Parse($buffer);
    if ($loadedClass->Validate() === true) { $found = true; break; }
}

if (!$found) { die("Unable to properly parse the uploaded file."); }

然而,这种做事方式并不适合我,我相信有更好的方法。

希望我能说清楚。

0 个答案:

没有答案