תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

הוספת פיצ'רים לקוד באמצעות דפוס תכנותי 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 מונחה עצמים

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

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

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

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

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

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

איך קוראים בעברית לצ`ופצ`יק של הקומקום?