簡體   English   中英

渲染而不破壞封裝

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM