תבנית המתאם
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 76 מתוך 91.
תבנית Adapter Pattern היא תבנית עיצוב מבנית שמאפשרת לאובייקטים עם ממשקים שאינם תואמים לעבוד יחד. היא משמשת כגשר בין שני ממשקים ומתרגמת קריאות מתבנית אחת לאחרת.
דמיינו שאתם בונים יישום שמעבד תשלומים, ואתם צריכים לשלב ספריית תשלומים של צד שלישי. הספרייה פועלת בצורה מושלמת, אבל הממשק שלה אינו תואם למה שהקוד שלכם מצפה לו. במקום לשכתב את כל היישום שלכם, אתם יוצרים מתאם שמתרגם בין השניים.
<?php
// הממשק שהיישום שלך מצפה לו
interface PaymentProcessor {
public function pay(float $amount): string;
}
// ספריית צד שלישי עם ממשק שונה
class StripeAPI {
public function createCharge(int $cents, string $currency): string {
return "Charged {$cents} {$currency} via Stripe";
}
}
המתאם מממש את הממשק המצופה שלך, ובתוך כך משתמש במחלקה של צד שלישי:
<?php
class StripeAdapter implements PaymentProcessor {
public function __construct(private StripeAPI $stripe) {}
public function pay(float $amount): string {
$cents = (int)($amount * 100);
return $this->stripe->createCharge($cents, 'USD');
}
}
$stripe = new StripeAPI();
$processor = new StripeAdapter($stripe);
echo $processor->pay(29.99);
פלט:
Charged 2999 USD via Stripeהמתאם ממיר דולרים לסנטים וקורא למתודה המתאימה. קוד היישום שלך מכיר רק את PaymentProcessor, ונשאר blissfully unaware מהדרישות הספציפיות של Stripe. אם בהמשך תעבור לספק תשלומים אחר, פשוט תיצור מתאם חדש בלי לשנות את הקוד הקיים שלך.
אתגר
קלבואו נבנה מערכת להמרת טמפרטורות באמצעות תבנית המתאם (Adapter Pattern). יש לכם חיישן טמפרטורה ישן שמספק קריאות בפרנהייט, אבל אפליקציית מזג האוויר המודרנית שלכם מצפה שכל הטמפרטורות יהיו בצלזיוס. במקום לשנות אחת מהמערכות, תיצרו מתאם שיגשר על הפער.
תארגנו את הקוד שלכם בארבעה קבצים:
TemperatureSensor.php: הגדירו ממשקTemperatureSensorשאפליקציית מזג האוויר שלכם מצפה לו. צריכה להיות בו מתודהgetTemperature(): floatשמחזירה את הטמפרטורה בצלזיוס.LegacySensor.php: צרו מחלקהLegacySensorשמדמה את החומרה הישנה. למחלקה הזאת יש ממשק שונה מזה שהאפליקציה שלכם צריכה:- היא מקבלת קריאת טמפרטורה בפרנהייט בבנאי שלה (השתמשו בקידום מאפיינים בבנאי)
- יש לה מתודה
readFahrenheit(): floatשמחזירה את ערך הפרנהייט שנשמר
LegacySensorAdapter.php: כללו את הממשק TemperatureSensor ואת המחלקה LegacySensor. צרו מחלקהLegacySensorAdapterשמממשת אתTemperatureSensorועוטפת אתLegacySensor. המתאם שלכם צריך:- לקבל
LegacySensorבבנאי שלו - לממש את
getTemperature()באמצעות קריאת ערך הפרנהייט מהחיישן הישן והמרתו לצלזיוס לפי הנוסחה:(fahrenheit - 32) * 5 / 9
- לקבל
main.php: כללו את הקובץ LegacySensorAdapter. תקבלו קלט אחד: טמפרטורה בפרנהייט.צרו
LegacySensorעם טמפרטורת הקלט, ואז עטפו אותו ב-LegacySensorAdapter. קראו ל-getTemperature()במתאם והדפיסו את התוצאה כשהיא מעוגלת לשתי ספרות אחרי הנקודה העשרונית.פורמט הפלט צריך להיות:
Temperature: [celsius]C
האתגר הזה מדגים איך תבנית המתאם מאפשרת לשלב ממשקים שאינם תואמים בלי לשנות קוד קיים. אפליקציית מזג האוויר שלכם עובדת אך ורק עם הממשק TemperatureSensor, בלי לדעת כלל שהקריאות בפועל מגיעות מחיישן ישן שמודד בפרנהייט.
נסו בעצמכם
<?php
require_once 'LegacySensorAdapter.php';
// קרא את הקלט
$fahrenheit = floatval(trim(fgets(STDIN)));
// TODO: צור LegacySensor עם טמפרטורת הקלט
// TODO: עטוף אותו ב-LegacySensorAdapter
// TODO: קרא ל-getTemperature() על המתאם
// TODO: הדפס את התוצאה מעוגלת לשתי ספרות אחרי הנקודה העשרונית
// תבנית הפלט: Temperature: [celsius]C
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים10מושגי OOP מתקדמים
הרכבה לעומת ירושההזרקת תלויותמחלקות אנונימיותטיפוסי Enum (PHP 8.1)סיבים (PHP 8.1)העמקה בשכפול אובייקטיםמחוללים ואיטרטורים13תבניות עיצוב חלק 2
תבנית הפקודהתבנית המתאםתבנית העיצובןתבנית שיטת התבניתתבנית המצבתבנית המורכבתבנית המאגר2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין