נגישות       נגישות
שינוי גודל טקסט:
א א א
שינוי צבעי האתר:
? מקשי קיצור:

לחיצה חוזרת ונשנית על המקש Tab תעביר אתכם בין הקישורים והאזורים השונים בעמוד.

הפעלת מקשי הקיצור תלויה בדפדפן שבו אתם משתמשים.

Internet Explorer, Chrome ובגרסאות ישנות של Firefox: לחצו על מקש Alt ועל מקש המספר או האות על-פי הרשימה. ב Firefox 3 ומעלה: לחצו על המקשים Alt + Shift + המספר או האות.

S - עבור לתוכן הדף
L - חיפוש
1- עמוד הבית
2 - פרוייקטים
3 - מדריכים
4 - אודות
5 - צרו קשר
6 - הצהרת נגישות
 

הוספת פיצ'רים לקוד באמצעות דפוס תכנותי Decorator

מחבר:
בתאריך:

משתמשים בדפוס תכנותי Decorator כדי להוסיף פונקציונאליות לקוד מבלי לשנות את המחלקות הקיימות, וזאת באמצעות הוספת מחלקות חדשות, ששייכות לאותו סוג של המחלקות הקיימות.

 

הבעיה

בדוגמה הבאה, חברה לייצור מכוניות משתמשת ב-interface כדי להגדיר לכל המחלקות המיישמות שהם חייבות לספק מחיר ותיאור של הרכב.

interface Car {
  function cost();
  function description();
}

החברה מייצרת 4 סוגי רכבים: SUV, Sedan ,Compact ו-Luxury.

כך מיושם ה-interface בשביל הסוג SUV.

class Suv implements Car {
    function cost()
    {
        return 170000;
    }

    function description ()
    {
           return "Suv";
    }
}

מחלקות דומות משמשות את יתר סוגי הרכבים (Sedan ,Compact ו-Luxury).

הבעיה מתחילה כשרוצים להכניס פריטים נוספים, שהקונה יכול לבחור אם להוסיף או לא, דוגמת: ג'נטים מגנזיום, ספוילרים במושבים וגג נפתח. כדי להכניס את הפריטים הנוספים צריך לשנות את הקוד של המחלקות הקיימות, מה שעלול לגרום להכנסת באגים בקוד שנבדק והוכיח את עצמו.

 

הפתרון

כשרוצים להוסיף למחלקות הקיימות תוספות שאינן הכרחיות משתמשים בדפוס תכנותי Decorator, ולפיו:

בנוסף למחלקות הבסיסיות שמיישמות את ה-interface, יוצרים קלאס אבסטרקטי שגם הוא מיישם את אותו ה-interface. הקלאס האבסטרקטי משמש סופר-קלאס שממנו יורשות המחלקות של התוספות.

 

הקלאס האבסטרקטי שהוא ה-Decorator

המחלקה האבסטרקטית CarFeature מהווה את הסופר-קלאס שממנו יורשות המחלקות של התוספות, ומיישמת את ה-interface Car:

abstract class CarFeature implements Car {
     protected $car;

     function __construct(Car $car)
     {
          $this->car = $car;
     }

     abstract function cost();
     abstract function description();
}

המחלקה האבסטרקטית CarFeature מיישמת את ה-interface Car באופן לא שגרתי, על ידי הגדרת המתודות שהיא יורשת מה-interface כאבסטרקטיות. בנוסף, המחלקה מחזיקה אובייקט שנוצר מאחת המחלקות הבסיסיות.

 

המחלקות הקונקרטיות שהם ה-subdecorator

עכשיו נוסיף את המחלקה הקונקרטית SunRoof שיורשת את המחלקה האבסטרקטית CarFeature.

class SunRoof extends CarFeature {
    function cost ()
    {
        return $this->car->cost() + 10000;
    }

    function description()
    {
        return $this->car->description() . ",  sunroof";
    }
}

באותו אופן, ניתן להוסיף קלאס Spoiler שנותן אפשרות להוסיף ספוילרים.

class Spoiler extends CarFeature {
    function cost ()
    {
        return $this->car->cost() + 8000;
    }

    function description()
    {
        return $this->car->description() . ",  spoiler";
    }
}

 

הפעלת הקוד

כדי ליישם את הקוד יוצרים אובייקט מאחד מהמחלקות הבסיסיות (SUV, Sedan ,Compact ו-Luxury), ומעבירים את האובייקט כפרמטר לקלאס שמייצר את התוספת הראשונה, את האובייקט שנוצר מהתוספת הראשונה מעבירים כפרמטר לתוספת השנייה, וכיו"ב, לפי מספר התוספות שרוצים להוסיף לדגם המכונית הבסיסי.

לדוגמה, רכב מסוג SUV עם גג נפתח.

$basicCar = new Suv();
$carWithSunRoof = new SunRoof($basicCar);

ועכשיו, מפעילים את המתודות כדי לגלות את מחירו ותיאורו של הרכב.

echo $carWithSunRoof -> description();
echo " costs ";
echo $carWithSunRoof -> cost();

תוצאה:

Suv, sunroof costs 180000

 

לדוגמה, רכב מסוג SUV עם גג נפתח וספוילרים במושבים.

$basicCar = new Suv();
$carWithSunRoof = new SunRoof($basicCar);
$carWithSunRoofAndSpoiler = new Spoiler($carWithSunRoof);

ועכשיו, מפעילים את המתודות כדי לגלות את מחירו ותיאורו של הרכב.

echo $carWithSunRoofAndSpoiler -> description();
echo " costs ";
echo $carWithSunRoofAndSpoiler -> cost();

תוצאה:

Suv, sunroof, spoiler costs 188000

סיכום

היתרון של שימוש ב-Decorator נובע מכך שאפשר להוסיף פונקציונאליות חדשה ואופציונאלית למחלקות הבסיסיות מבלי לשנות את הקוד הקיים, שכבר נבדק והוכיח את עצמו.

 

אני ממליץ ללמוד PHP מונחה עצמים עם "The essentials of Object Oriented PHP" שהוא הספר שעליו מבוססים רוב המדריכים בנושא באתר רשתטק.
הקליקו על התמונה כדי לרכוש את ה-eBook:

eBook cover The essentials of Object Oriented PHP

 

לכל מדריכי ה-PHP מונחה עצמים

הוסף תגובה חדשה

 

= 4 + 8