我将尝试尽可能深入地解释我对班级模型的想法,以便(希望)为潜在的答案提供更好的基础。
我构建了一个类,它解析来自应用程序的数据,这些应用程序共享一个 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
不同方式读取数组并将数据设置为 $handledData
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."); }
然而,这种做事方式并不适合我,而且我确信有更好的方式来做这件事。
希望我说清楚了。