|
טיפ: callback וצורת כתיבת קוד
למי מביניכם שיצא כבר לנסות לכתוב מערכות, בטח נתקל במצב בו הוא שואל את עצמו "איך אתכנן את מחלקת ה-skin בצורה הטובה ביותר כדי שהקוד ייראה הכי טוב שאפשר וגם יהיה יעיל?".
כידוע קוד PHP רץ הרבה יותר מהר מקוד SQL, ולכן בדר"כ לא מקפידים בנושא הייעול בו (מלבד דברים ברורים) כמו שמקפידים בקוד SQL. אבל אני פרפקטציוניסט שלא יכול לסבול דברים בסיגנון של קוד לא אסתטי ושהוא מיותר.
דוגמא לקוד מיותר, כפי שמתכנתים מתחילים אולי היו כותבים את מחלקת ה-skin הנ"ל, הוא כקוד הבא:
קוד PHP:
class skin
{
// some stuff here ...
function table_row_start($text)
{
echo '<tr><td>', $text, '</td><td>';
}
function input_text($id, $init_value='')
{
echo '<input type="text" name="',$id,'" id="',$id,'" value="',$init_value,'" />'; # `name` and `id` considered the same
}
function table_row_end()
{
echo '</td></tr>';
}
}
$skin = new skin;
$skin->table_row_start('First name:');
$skin->input_text('f_name', '');
$skin->table_row_end();
דוגמא נוספת:
קוד PHP:
class skin
{
// some stuff here ...
function table_row($text, $field)
{
echo '<tr><td>', $text, '</td><td>',$field,'</td></tr>';
}
function input_text($id, $init_value='')
{
return '<input type="text" name="',$id,'" id="',$id,'" value="',$init_value,'" />'; # `name` and `id` considered the same
}
}
$skin = new skin;
$skin->table_row_start('First name:', $skin->input_text('f_name', ''));
באפשרות הראשונה מה שמציק לי זה האקסטרא קוד שכותבים.
באפשרות השנייה מה שמציק זה ה-return שיש בפונקציית input_text ובכל הפונקציות האחרות שקשורות לפונקציית ה-skin.
אני יודע שאלו דברים שהם "לא כזה נורא" או גם "לא נורא בכלל" אבל אני אישית לא יכול להסתדר עם זה.
אז באה לעזרתי אפשרות ה-callback שאיתה מעבירים את שם הפונקציה כפרמטר, וגם מעבירים את פרמטרי הפונקציה הזאת בפרמטר אחר כשהם בתוך מערך.
דוגמא לקוד שנעזר ב- callback יהיה:
קוד PHP:
class skin
{
function table_row($text, $callback, array $param)
{
echo '<tr><td>', $text, '</td><td>';
call_user_func_array(array($this, $callback), $param);
echo '</td></tr>';
}
function input_text($id, $init_value)
{
echo '<input type="text" name="',$id,'" id="',$id,'" value="',$init_value,'" />'; # `name` and `id` considered the same
}
}
$skin = new skin;
$skin->table_row('First name:', 'input_text', array('f_name', ''));
כעת הקוד יותר אסתטי ובלי return'ים מעצבנים לעין.
אבל אז היה אפשר לומר, למה לא פשוט לכתוב את פונקציות ה-field בצורה כזו שה- table_row כלול בתוכם, כלומר:
קוד PHP:
class skin
{
// ...
function input_text($text, $id, $init_value)
{
echo '<tr><td>',$text,'</td><td>
<input type="text" name="',$id,'" id="',$id,'" value="',$init_value,'" />',
'</td></tr>';
}
}
הסיבה שלא כדאי לעשות זאת היא שכנראה בעתיד יהיה צורך אך ורק בפונקצית ה- input_field, בלי החלק של המעטפת שכוללת את התגים td ו- tr. מהסיבה הזו גם ניקבע חוק הנירמול (מקוה שאני לא טועה בשמו), שבו חובה שכל אלמנט יהיה מבודד. חוק זה מיושם גם בתיכנון מבנה מסדי נתונים.
מקוה שעזרתי כאן למישהו שגם בשבילו זה היווה בעיה. בהצלחה.
נ.ב. קיויתי שיש אפשרות שפונקציות callback לוקחות מהמערך רק את הפרמטרים שיש להם key שהוא מספר (או לפחות key שלא הגדירו אותו עבור האיבר), ולא key שהוא אסוציאטיבי (מילולי, אותיות), אבל לצערי גם האיברים שיש להם key אסוציאטיבי יכולים להיחשב כפרמטרים של פונקציית ה-callback.
הסיבה היא שאולי אפשר לנצל את הקיום של המערך הזה ולקחת ממנו את המידע, במקום להוסיף פרמטרים למתודה table_row.
נערך לאחרונה ע"י dorM בתאריך 12-02-2009 בשעה 19:39.
|