Abstract Factory
Administrator 7/8/2021 OOPPattern
# Description
- Create các object mà không cần chỉ định class cấu trúc.
# Example:
Create view template for the page
interface ViewFactory
{
public function getPageTemplate(): PageTemplate;
public function getRenderer(): Renderer;
}
1
2
3
4
5
6
2
3
4
5
6
interface PageTemplate
{
public function getStringTemplate(): string;
}
1
2
3
4
2
3
4
interface Renderer
{
public function render(string $templateString, array $arguments = []): string;
}
1
2
3
4
2
3
4
class Page
{
public function render(ViewFactory $factory, $arguments): string
{
$renderer = $factory->getRenderer();
$pageTemplate = $factory->getPageTemplate();
$viewPath = $pageTemplate->getStringTemplate();
return $renderer->render($viewPath, $arguments);
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Use PHP để render view:
class PHPTemplateFactory implements ViewFactory
{
public function getRenderer(): Renderer
{
return new PHPTemplateRenderer();
}
public function getPageTemplate(): PageTemplate
{
return new PHPPageTemplate();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
class PHPPageTemplate implements PageTemplate
{
public function getStringTemplate(): string
{
return <<<HTML
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title><?= \$title; ?></title> </head> <body> <?= \$content; ?> </body> </html>
HTML;
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
class PHPTemplateRenderer implements Renderer
{
public function render(string $templateString, array $arguments = []): string
{
extract($arguments);
ob_start();
eval(' ?>' . $templateString . '<?php ');
$result = ob_get_contents();
ob_end_clean();
return $result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Use twig engine:
class TwigFactory implements ViewFactory
{
public function getRenderer(): Renderer
{
return new TwigRenderer();
}
public function getPageTemplate(): PageTemplate
{
return new TwigPageTemplate();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
class TwigPageTemplate implements PageTemplate
{
public function getStringTemplate(): string
{
return "index.html";
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
class TwigRenderer implements Renderer
{
public function render(string $templatePath, array $arguments = []): string
{
$loader = new \Twig\Loader\FilesystemLoader('/../src/Libs/Views');
$twig = new \Twig\Environment($loader, [
'cache' => '/../cache',
]);
return $twig->render($templatePath, $arguments);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Usage:
$page = new Page();
$viewFactory = new PHPTemplateFactory();
echo $page->render($viewFactory, ["title" => "Page title", "content" => "Page content"]);
1
2
3
2
3
Renderer, PageTemplate được create bằng Factory Method
- User không cần biết logic xử lí, chỉ cần quan tâm các method của nó thông qua interface.
- Muốn thay đổi template engine chỉ cần tạo Renderer, PageTemplate độc lập mà không cần update lại code xử lí ở Page.
Refer: https://refactoring.guru/design-patterns/abstract-factory/php/example