Page Controller (Контроллер страницы)

Паттерн проектирования Page Controller

Паттерн проектирования Page Controller

Описание Page Controller

Объект, обрабатывающий запрос к отдельной странице или действию.

Большинство людей получают первый опыт в веб-программировании на статичных HTML-страницах. Когда происходит запрос к статической HTML-странице, веб-серверу передаётся имя и путь к хранящемуся на нём HTML-документу. Главная идея здесь в том, что каждая страница на веб-сайте является отдельным документом, хранящимся на сервере. В случае с динамическими страницами всё гораздо сложнее, так как сложнее связь между введённым адресом и отображённой страницей. Тем не менее, подход, когда один путь соответствует одному файлу, который обрабатывает запрос достаточно очевиден и прост для понимания.

В результате контроллер страницы (Page Controller) - паттерн, в котором один контроллер отвечает за отображение одной логической страницы. Это может быть как отдельная страница, хранящаяся на веб-сервере, так и отдельный объект, который отвечает за страницу.

Примеры реализации

// Page Controller Pattern in JavaScript
class PageController {
    constructor(request, response) {
        this.request = request;
        this.response = response;
    }
    
    handleRequest() {
        throw new Error('handleRequest method must be implemented');
    }
    
    render(template, data = {}) {
        let html = template;
        for (const [key, value] of Object.entries(data)) {
            html = html.replace(new RegExp(`{{${key}}}`, 'g'), value);
        }
        return html;
    }
}

class HomePageController extends PageController {
    handleRequest() {
        const template = `
            
            
            
                {{title}}
            
            
                

{{title}}

{{message}}

`; const data = { title: 'Welcome to Our Site', message: 'This is the home page' }; this.response.setHeader('Content-Type', 'text/html'); this.response.end(this.render(template, data)); } } // Usage console.log('Page Controller pattern implemented');
<?php
// Page Controller Pattern in PHP
abstract class PageController {
    protected $request;
    protected $response;
    
    public function __construct($request, $response) {
        $this->request = $request;
        $this->response = $response;
    }
    
    abstract public function handleRequest();
    
    protected function render($template, $data = []) {
        $html = $template;
        foreach ($data as $key => $value) {
            $html = str_replace("{{$key}}", $value, $html);
        }
        return $html;
    }
}

class HomePageController extends PageController {
    public function handleRequest() {
        $template = '
            
            
            
                {{title}}
            
            
                

{{title}}

{{message}}

'; $data = [ 'title' => 'Welcome to Our Site', 'message' => 'This is the home page' ]; header('Content-Type: text/html'); echo $this->render($template, $data); } } echo "Page Controller pattern implemented"; ?>
// Page Controller Pattern in Go
package main

import (
    "fmt"
    "html/template"
    "net/http"
)

type PageController interface {
    HandleRequest(w http.ResponseWriter, r *http.Request)
}

type HomePageController struct{}

func (hpc *HomePageController) HandleRequest(w http.ResponseWriter, r *http.Request) {
    templateStr := `
        
        
        
            {{.Title}}
        
        
            

{{.Title}}

{{.Message}}

` data := map[string]interface{}{ "Title": "Welcome to Our Site", "Message": "This is the home page", } tmpl, err := template.New("page").Parse(templateStr) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } err = tmpl.Execute(w, data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } func main() { homeController := &HomePageController{} http.HandleFunc("/", homeController.HandleRequest) fmt.Println("Server starting on :8080") fmt.Println("Page Controller pattern implemented") http.ListenAndServe(":8080", nil) }

Использована переведённая иллюстрация с сайта Мартина Фаулера.

Источник