سرفصل‌های آموزشی
آموزش الگوهای طراحی (Design Pattern)
آشنایی با الگوی طراحی Template

آشنایی با الگوی طراحی Template

در این آموزش قصد داریم تا با Template Design Pattern آشنا شویم و به بررسی کاربردهای آن در برنامه‌نویسی شیئ‌گرا در قالب مثالی فرضی در زبان برنامه‌نویسی PHP بپردازیم. به طور کلی، دیزاین پترن تمپلیت زیرشاخۀ الگوهای طراحی Behavioral است و استفاده از آن در شرایطی مفید واقع می‌شود که برخی فیچرهایی مشترک برای چند کلاس مد نظر داریم به طوری که پیاده‌سازی آن‌ها در تک‌تک کلاس‌های مذکور منجر به اصطلاحاً Duplication در سورس‌کد می‌شود اما با استفاده از این دیزان پترن می‌توان ساختار کلی الگوریتم مد نظر و همچنین متدهای مشترک مابین کلاس‌های مذکور را در تنها یک کلاس به اصطلاح Template پیاده‌سازی کرده و هر کلاس فرزندی که از آن ارث‌بری کند باید متدها و فیچرهای مد نظر متناسب با نیاز خود را بیفزاید. به عبارتی، یک اسکلت یا قالب اصلی وجود دارد که کلیهٔ ساب‌کلاس‌ها از آن قالب تبعیت کرده اما در عین حال هر کدام کدهای اختصاصی خود را دارند.

حال به منظور درک بهتر ساختار دیزاین پترن تمپلیت و پیاده‌سازی این الگوی طراحی مثالی را در نظر می‌گیریم که در آن قصد داریم تا کلاسی مجزا به منظور چاپ استرینگ مربوط به نام کتابی برای پرینت گرفتن از آن و کلاسی دیگر برای چاپ استرینگ مربوط به نام کتاب الکترونیکی مد نظر برای تهیۀ فایل پی‌دی‌اف از آن را پیاده‌سازی کنیم به طوری که هر دو کلاس مذکور ویژگی‌های مشترکی همچون متدی برای چاپ نام مربوطه را از کلاس تمپلیت ارث‌بری خواهند کرد. برای این منظور، پوشه‌ای تحت عنوان template-design-pattern در لوکال‌هاست تعریف کرده و در ادامه فایل‌های پروژۀ خود را بر اساس ساختار زیر ایجاد می‌کنیم:

template-design-pattern/
├── Book.php
├── Ebook.php
├── index.php
└── PaperBack.php

پیش از هر توضیحی، لازم به یادآوری است که تمامی فایل‌های این آموزش با دستور php?> شروع می‌شوند که به دلیل شلوغ نشدن کدها، از نوشتن آن در تمامی اسکریپت‌ها خودداری کرده‌ایم.

کلاس اَبسترکت چیست؟
Abstract Class زمانی استفاده می‌شود که بخواهیم دولوپرها را موظف سازیم تا در حین ارث‌بری حتماً متد خاصی را پیاده‌سازی کنند و این در حالی است که صرفاً در مورد نام متد اطمینان داریم و نمی‌دانیم الگوریتم داخلش به چه شکل باید باشد. زمانی که کلاسی از جنس اَبسترکت می‌نویسیم، موظف هستیم تا حداقل یک متد از جنس اَبسترکت نیز داخل آن کلاس تعریف نماییم و لازم به توضیح است که متدهای اَبسترکت فقط حاوی نام و احتمالاً آرگومان‌های ورودی هستند که با این تفاسیر هرگز قادر به ساخت آبجکت از روی کلاس‌های اَبسترکت نخواهیم بود بلکه برای ساخت یک آبجکت، ابتدا باید یک کلاس فرزند بسازیم که از کلاس اَبسترکت والد ارث‌بری کرده باشد سپس الگوریتم مد نظر خود را داخل کلاس فرزند پیاده‌سازی نماییم.

به نوعی می‌توان کلاس‌های اَبسترکت را به اینترفیس‌ها تشبیه کرد با این تفاوت که اینترفیس یک کلاس اَبسترکت است که کلیهٔ متدهایش اَبسترکت می‌باشند اما این در حالی است که در کلاس‌های اَبسترکت علاوه بر حداقل یک متد اَبسترکت، می‌توان متدهای معمولی نیز داشت.

حال با در نظر گرفتن توضیحات فوق، در ابتدا کلاسی تحت عنوان Book را در فایلی به نام Book.php ساخته به طوری که حاوی فیچرها و فانکشن‌های مشترک مابین کلاس‌های PaperBack و Ebook است:

abstract class Book {
    abstract public function generateName($name);
}

همان‌طور که مشاهده می‌کنید، با قرار دادن کلیدواژهٔ abstract قبل از نام کلاس، کلاسی از نوع اَبسترکت تحت عنوان Book ساخته‌ایم تا در نقش یک قالب به اصطلاح Parent (والد) بوده که حاوی متدی است که مابین کلیهٔ کلاس‌های Child (فرزند) مشترک خواهد بود. در ادامه فانکشنی از جسن اَبسترکت به نام ()generateName با یک آرگومان ورودی تحت عنوان name$ پیاده‌سازی کرده‌ایم که این وظیفه را دارا است تا نام کتاب را به عنوان پارامتر ورودی گرفته و آن را چاپ کند.

همان‌طور که پیش از این گفتیم که از روی کلاس‌های اَبسترکت نمی‌‌توان آبجکت ساخت، لذا نیاز است تا بسته به نیاز وب اپلیکیشن خود دست به ساخت یکسری کلاس فرزند بزنیم بدین صورت که برای متد اَبسترکتِ داخل کلاس اَبسترکتِ فوق Body (بدنه) تعریف شود که برای همین منظور در این مرحله متناسب با نیاز پروژۀ خود کلاسی تحت عنوان PaperBack را داخل فایلی به نام PaperBack.php و به منظور چاپ استرینگ مربوط به نام کتاب‌ مد نظر برای پرینت گرفتن از آن پیاده‌سازی می‌کنیم که در همین راستا فایل مذکور را بدین صورت تکمیل می‌کنیم:

require_once 'Book.php';
class PaperBack extends Book {
    public function generateName($name) {
        echo "The Book Name Is \"$name\" & Should Be Printed.";
    }
}

در کد فوق کلاسی به نام PaperBack ساخته و آن را از کلاس Book ارث‌بری کرده‌ایم که بدین ترتیب به چارچوب کلی این کلاس دسترسی داشته و موظف هستیم تا برای فانکشن اَبسترکت ()generateName منطقی خاص این کلاس تعریف کنیم که این منطق عبارت است از چاپ نام کتاب (پارامتر ورودی) داخل علائم دابل‌کوتیشن (در واقع، قرار دادن علامت / قبل از " منجر به این خواهد شد که این علامت توسط مفسر پی‌اچ‌پی در خروجی چاپ شود.)

همچنین کلاسی دیگر تحت عنوان Ebook را داخل فایلی به نام Ebook.php و به منظور چاپ استرینگ مربوط به نام کتاب الکترونیکی مد نظر برای تهیۀ فایل پی‌دی‌اف از آن توسعه می‌دهیم که برای این منظور کدی مانند زیر خواهیم داشت:

require_once 'Book.php';
class Ebook extends Book {
    public function generateName($name) {
        echo "A PDF Was Generated for The eBook \"$name\".";
    }
}

در کد فوق، ابتدا فایل مربوط به کلاس پَرنت را ایمپورت کرده و در ادامه کلاسی به نام Ebook ساخته‌ایم که از کلاس اَبسترکت Book ارث‌بری می‌کند و در ادامه فانکشن اَبسترکت ()generateName را تکمیل کرده‌ایم بدین صورت که پارامتر ورودی مربوط به نام کتاب الکترونیکی مد نظر را داخل علائم " " قرار داده و با استرینگ «.A PDF Was Generated for The eBook» کانکت کرده و در خروجی چاپ می‌کند.

حال برای تست اپلیکیشن، کدهای زیر را در فایل index.php نوشته و آن را اجرا می‌کنیم:

require_once 'PaperBack.php';
$paperback = new PaperBack();
$paperback->generateName("Good to Great");

در کد فوق ابتدا فایل‌ مربوطه را ایمپورت کرده و در ادامه آبجکتی تحت عنوان paperback$ از روی کلاس PaperBack ساخته‌ایم که در ادامه فانکشن ()generateName را روی آبجکت ساخته‌شده فراخوانی می‌کنیم و استرینگ فوق را به عنوان پارامتر ورودی به آن می‌دهیم که در نهایت استرینگ زیر را در خروجی خواهیم داشت:

The Book Name Is "Good to Great" & Should Be Printed.

اکنون به منظور تست عملکرد کلاس Ebook کدهای قبل را از فایل index.php پاک کرده و کدهای زیر را در آن می‌نویسیم:

require_once 'Ebook.php';
$ebook = new Ebook();
$ebook->generateName("PHP & MySQL FOR Dummies");

عملکرد کلاس فوق نیز مشابه کلاس پیشین می‌باشد با این تفاوت که فراخوانی فانکشن ()generatePdf از کلاس Ebook در نهایت منجر به چاپ استرینگ زیر در خروجی خواهد شد:

A PDF Was Generated for The eBook "PHP & MySQL FOR Dummies".

همان‌طور که می‌بینید، پارامتر ورودی مربوط به نام کتاب الکترونیکی داخل علائم دابل‌کوتیشن با استرینگ مد نظر کانکت شده و در معرض دید ما قرار گرفته است.

جمع‌بندی
به طور کلی، دیزاین پترن تمپلیت ساده‌ترین نوع از الگوهای طراحی بوده و به منظور کاهش کدهای مشابه در هر یک از کلاس‌های اپلیکیشن و انتقال آن‌ها به کلاس تمپلیت مورد استفاده قرار می‌گیرد به طوری که کلاس‌های مذکور ویژگی‌های مشابه را از آن ارث‌بری می‌کنند که این امر منجر به سادگی سورس‌کد می‌شود.

online-support-icon