根据字符串选择HTML模板:Factory还是Strategy模式?
Great question! Let’s break down the core differences between these two patterns, then map them directly to your use case where you need to render a specific HTML template based on a string input like $form = "formRegistration".
First, Clarify Each Pattern’s Core Purpose
Factory Pattern: Focused on Object Creation
The Factory pattern is all about encapsulating the logic to create different objects based on input. It’s perfect when you need to generate distinct instances (each representing a specific thing, like a form template) without exposing the messy creation details to your main code.
Think of it as a "form factory" that takes your string input and hands you back the exact form template object you need—no messy if/else chains cluttering up your main logic.
Strategy Pattern: Focused on Behavior Switching
The Strategy pattern is for encapsulating interchangeable behaviors (algorithms, actions) that a context can use. It’s useful when you have a core process (like handling a form submission + rendering) and need to swap out one part of that process (the rendering step) based on input.
The key here is that Strategy is about behavior, not object creation. You’re not making new objects to represent the form itself—you’re swapping out how the form gets rendered within an existing workflow.
Applying to Your Specific Scenario
Your current code is a simple conditional:
if ($form == "formRegistration") { echo include("formRegistration.php"); }
Let’s map this to both patterns:
- If your only goal is to get the right form template and render it (no extra logic like validation, submission handling), the Factory pattern is the more direct fit. It aligns perfectly with creating and returning the right form template instance.
- If you’re building a more complete form system where rendering is just one step (e.g., you also validate inputs, handle submissions, etc.), Strategy makes sense—you can swap the rendering strategy while keeping the rest of the workflow consistent.
Example Implementations
Factory Pattern Implementation
First, define an interface for all form templates:
interface FormTemplate { public function render(): string; }
Then create concrete classes for each form:
class RegistrationForm implements FormTemplate { public function render(): string { ob_start(); include("formRegistration.php"); return ob_get_clean(); } } class LoginForm implements FormTemplate { public function render(): string { ob_start(); include("formLogin.php"); return ob_get_clean(); } }
Build the factory to create the right form:
class FormFactory { public static function create(string $formType): FormTemplate { $formMap = [ "formRegistration" => RegistrationForm::class, "formLogin" => LoginForm::class ]; if (!isset($formMap[$formType])) { throw new InvalidArgumentException("Invalid form type: {$formType}"); } return new $formMap[$formType](); } }
Use it in your code:
$formType = "formRegistration"; $form = FormFactory::create($formType); echo $form->render();
Strategy Pattern Implementation
This makes sense if you have a broader form handling workflow. First, define the rendering strategy interface:
interface FormRenderStrategy { public function render(): string; }
Implement strategies for each form:
class RegistrationRenderStrategy implements FormRenderStrategy { public function render(): string { ob_start(); include("formRegistration.php"); return ob_get_clean(); } } class LoginRenderStrategy implements FormRenderStrategy { public function render(): string { ob_start(); include("formLogin.php"); return ob_get_clean(); } }
Create a context class that handles the full form workflow:
class FormHandler { private $renderStrategy; public function __construct(FormRenderStrategy $renderStrategy) { $this->renderStrategy = $renderStrategy; } public function setRenderStrategy(FormRenderStrategy $renderStrategy): void { $this->renderStrategy = $renderStrategy; } public function processForm(): void { // Add shared logic here: validate inputs, handle submission, etc. // ... // Render using the selected strategy echo $this->renderStrategy->render(); } }
Use it in your code:
$formType = "formRegistration"; $strategyMap = [ "formRegistration" => new RegistrationRenderStrategy(), "formLogin" => new LoginRenderStrategy() ]; $formHandler = new FormHandler($strategyMap[$formType]); $formHandler->processForm();
Final Recommendation
- Go with the Factory pattern if your needs are simple: just fetching and rendering the right form template. It’s straightforward, keeps your creation logic centralized, and is easy to extend when you add new forms.
- Choose the Strategy pattern only if you’re building a more complex system where rendering is one part of a larger form-handling process (like validation, submission tracking, etc.). It gives you flexibility to swap rendering behaviors without changing the core workflow.
内容的提问来源于stack exchange,提问作者Haima

