[英]Rendering without breaking encapsulation
在不破壞封裝的情況下實現此目的的正確方法是什么? 我保持示例簡單,但如果我決定添加更多實體,解決方案應該可以很好地擴展。 我有一個學生和類似的課程:
class Student {
private $id;
private $name;
/**
* Courses student is attending
* @var Course[]
*/
private $courses = array();
private $numberOfAttendingCourses;
}
class Course {
private $code;
}
讓我們說我想渲染一下:
<ul>
<li>[studentName] ([numberOfAttendingCourses])</li>
</ul>
這也是另一個用例的觀點
<ul>
<li>[studentName] (ID: [studentId])
<ul>
<li>[course1Name] ([course1Code])</li>
<li>[course2Name] ([course2Code])</li>
</ul>
</li>
</ul>
我知道如何使用getter和setter來實現它。 我對保持兩個對象盡可能封裝的方式感興趣。
最簡單的方法是將值結構傳遞給模板渲染器。 這將使您免於在模板本身內做太多邏輯。
例如 - 首先為您的可渲染類創建一個接口
class Renderable {
public function getViewData();
}
然后讓您的學生和課程類符合界面。
class Student implements Renderable{
private $id;
private $name;
/**
* Courses student is attending
* @var Course[]
*/
private $courses = array();
private $numberOfAttendingCourses;
public function getViewData(){
$dat = array("id"=>$this->id, "name"=>$this->name, "courses"=>array());
foreach($this->courses as $course){
$dat["courses"][] = $course->getViewData();
}
$dat["numCourses"] = count($dat["courses"]);
return $dat;
}
}
class Course implements Renderable{
private $code;
private $name;
public function fetchViewData(){
return array("code"=>$this->code,
"name"=>$this->name);
}
}
創建模板解析器。
class Template {
public function render($templateFile, array $data){
if ($data instanceof Renderable){
$data = $data->getViewData();
}
extract ($data);
ob_start();
include($templateFile);
ob_get_clean();
}
}
然后是一個簡單的標記模板
<ul>
<li><?= htmlspecialchars($name) ?> (ID: <?= htmlspecialchars($id) ?>)
<ul>
<?php foreach($courses as $course): ?>
<li><?= htmlspecialchars($course["code"]) ?> (<?= htmlspecialchars($course["code"]) ?>)</li>
<?php endforeach; ?>
</ul>
</li>
</ul>
一旦你有一個有效的學生對象,你可以簡單地
$template = new Template();
$template->render("/path/to/template.phtml", $student->fetchViewData());
這也應該使您可以非常簡單地開發和測試模板,因為您可以使用可維護的數組,而不是去創建學生和一堆Course對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.