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

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

מתי והיכן להשתמש ב-traits?

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

ב-PHP מותר לרשת ממחלקה אחת בלבד, אבל לעיתים אנחנו צריכים לרשת את הקוד שלנו מיותר ממקור אחד. במקרים כאלה, ניתן להוסיף עוד ועוד הורים לשרשרת ההורשה. הבעיה היא שאנו עלולים בקלות להגיע לשרשרת הורשה ארוכה שמסבכת את העניינים, ובאופן כללי עדיף לא לחרוג מיותר משלושה דורות של הורשה. דרך נוספת להתמודדות עם אותה בעיה היא באמצעות הכללת הקוד שאנו זקוקים לו (באמצעות include או require) ישירות לתוך המחלקה. גישה זו היא אומנם כשרה אבל מעט מסריחה.

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

 

eBook cover The essentials of Object Oriented PHP

 

כיצד trait עובד?

Trait דומה למחלקה בזה שהוא מקבץ קוד. התחביר לדוגמה:

trait TraitName {
  // trait code
}

בדוגמה הבאה, trait ששמו Price מחזיק את המתודה ששמה changePriceByDollars, שמחשבת את המחיר החדש מהישן, תוך התחשבות בשינוי המחיר בשקלים.

trait Price {
  public function changePriceByDollars($price, $change)
  {
    return $price + $change;
  }
}

אחרי שיצרנו את ה-trait, אנו יכולים להשתמש בו במחלקות באמצעות מילת המפתח use. בדוגמה הבאה, שתי המחלקות, Bmw ו-Mercedes משתמשים ב-Trait.

class Bmw {
  use Price;
}
 
class Mercedes {
  use Price;
}

כדי לראות את הקוד בפעולה, ניצור אובייקטים מהמחלקות, ואז נשתמש במתודה changePriceByDollars, שאותה הם קיבלו מה-trait.

$bmw1 = new Bmw();
// Add 3000$
echo $bmw1 -> changePriceByDollars(45000, +3000);
 
$mercedes1 = new Mercedes();
// Subtract 2100$
echo $mercedes1 -> changePriceByDollars(42000, -2100);

תוצאה:

48000
39900

מהדוגמה הזו אנו יכולים ללמוד שניתן להשתמש בקוד מה-trait במחלקות באותה הקלות שבה משתמשים ב-include.

 

האם מחלקות יכולות להשתמש ביותר מ-trait אחד?

מחלקה יכולה להשתמש ביותר מ-trait אחד, הרי לשם כך הומצאו ה-traits. כדי להדגים זאת, בואו נוסיף לקוד trait נוסף ששמו SpecialSell, ובו מתודה ששמה annonunceSpecialSell, שמודיעה על מכירות מיוחדות. בואו נראה כיצד האובייקט שיצרנו מהמחלקה Mercedes יכולה להשתמש בשני ה-trait-ים.

trait Price {
  public function changePriceByDollars($price, $change)
  {
    return $price + $change;
  }
}
  
trait SpecialSell {
  public function annonunceSpecialSell ()
  {
    return __CLASS__ . " on special sell";
  }
}
  
  
class Mercedes {
  use Price;
  use SpecialSell;
}
  
$mercedes1 = new Mercedes();
// Subtract 2100$
echo $mercedes1 -> changePriceByDollars(42000, -2100);
echo $mercedes1 -> annonunceSpecialSell();

תוצאה:

39900
Mercedes on special sell

 

כיצד trait שונה מהורשה רגילה?

Trait-ים משתמשים בצורה מיוחדת של הורשה שמאפשרת להם לכלול קוד ממספר traitים. צורה זו של הורשה מכונה הורשה אופקית (horizontal inheritance), והיא זו שמאפשרת את הכללת הקוד מה-trait במחלקות היורשות. זה דומה לשימוש בפקודות require או include, אבל נראה הרבה יותר מסודר.

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

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

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

trait Price {
  // The method needs the $price property.
  public function changePriceByDollars($change)
 {
    return $this -> price += $change;
 }
}
 
 
class Mercedes {
  use Price;
 
  // The $price is private.
  private $price;
  
  public function __construct($price)
  {
    $this -> price = $price;
  }
  
  public function getPrice()
  {
    return $this -> price;
  }
}
  
  
$mercedes1 = new Mercedes(42000);
echo $mercedes1 -> getPrice();
$mercedes1 -> changePriceByDollars(-2100);
echo $mercedes1 -> getPrice();

תוצאה:

42000
39900

מדוגמה זו אנו יכולים ללמוד שלמתודה שנמצאת בתוך ה-trait יש גישה לתכונות ולמתודות פרטיים בתוך הקלאס שירש אותו.

 

מה יתרונות השימוש ב-trait?

Trait –ים מאפשרים למחלקות להשתמש בקוד מיותר ממקור אחד, ובכך, מאפשר לנו לעקוף את המגבלה של ירושה ממחלקה אחת בלבד.

 

מה חסרונות השימוש ב-traits?

בגלל האופי פורץ הגבולות של ה-trait, כדאי להיזהר משכפול הקוד בין trait-ים שונים, ומהתנגשות בין שמות המשתנים והפונקציות מהמקורות השונים.

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

 

באילו מקרים כדאי במיוחד להשתמש ב-trait?

במקרים מסוימים השימוש ב-traits יכול להוכיח את עצמו עדיף על הורשה רגילה. לדוגמה, כאשר מספר מחלקות מיישמות את אותו interface ולפיכך יורשות את הקוד שלו, אבל רק חלק מאותן המחלקות (ולא כולן) צריכות חלקים של הקוד. זה הגיוני להשתמש בהורשה רגילה לאותם המתודות שחולקות כל המחלקות, בעוד עדיף להשתמש ב-trait-ים עבור אותם מתודות שצריך רק בחלק מהמחלקות. לדוגמה, אם יש לנו שלוש מחלקות שיורשות את ה-interface ששמו Car (Bmw, Mercedes, Audi), ואנחנו צריכים את המתודה שמטפלת במכירה מיוחדת רק בשתיים מהמחלקות, נאמר על ה-Bmw וה-Mercedes בלבד, נעדיף להשתמש לשם כך ב-trait, כדי שהקוד ישותף רק בין המחלקות שצריכות אותו.

 

לסיכום

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

 

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

eBook cover The essentials of Object Oriented PHP

 

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

 

 

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

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

 

 

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

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

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

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

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

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

 

 

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

דג למים הוא כמו ציפור ל...?