שאלה ב design

eyal the one

New member
שאלה ב design

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

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

eyal the one

New member
לא נכון

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

אלדד28

New member
תלוי איזו מחלקה זו.

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

ChipsMan

New member
ובנוסף, יש עוד עניין קטן..

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

eyalbd

New member
זה לא overhead

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

זה מה שצ'יפס אמר... מתודות רגילות מעבירות את ה-this (מצביע לאובייקט) כפרמטר "חבוי" (כלומר - הוא על המחסנית למרות שלא הופיע במפורש ברשימת הפרמטרים). התופעה הזו לא קוראת במתודות סטטיות של מחלקה (כי היא לא בהכרח תקרא מתוך אובייקט).
 
זה מעבר ל-overhead...../images/Emo26.gif

זה גם צורם משיקולי הנדסת תוכנה... אם יש לך מתודה שבמהות שלה לא משתמשת או משנה לך את האובייקט - אתה צריך להגדיר אותה כ-static (אפילו אם לא תהיה לזה שום השפעה על דרך הפעולה של התוכנית). מעבר לפונקציונליות של static (שמאפשרת לך לקרוא למתודה מבלי ליצור אובייקט) - יש כאן גם עניין "הצהרת-כוונות" בהיבט של design נכון...
 

the new L

New member
למה מחלקה????

בדיוק בשביל זה יש NAMESPACES! פשוט תאגד את כל הפונקציות הללו ב NAMESPACE משותף.
 

rubens1

New member
האמנם?

הפונקציות הנ"ל סביר להניח שיצטרפו למחלקה שמייצגת כתובת IP, ומכילה כל מיני פונקציות לשינוי אותה כתובת IP. כמו למשל Make Subnet(הופכת כתובת IP לכתובת של Subnet, על ידי איחודה עם Subnet Mask), כמו IsAddressMulticast, כמו RandAddressInSubnet(מגרילה כתובת IP הנמצאת בתוך Subnet כלשהו), כמו GetMulticastMacAddress(המשיגה את כתובת הmac המתאימה להודעת IP multicast כלשהי), ConvertStringToIp, ConvertIpToString אבל חוץ מזה? סביר להניח שאפשר גם למצוא פונקציות שלא קשורות ישירות לclass כלשהו, ולא משנות את הממברים שלו. דוגמה? GetRandomMulticastIp, GetRandomIp, וכו'. namespaces זה ממש אבל ממש לא לאיגוד פונקציות. namespace הוא בדיוק מה ששמו מעיד: משהו שנועד למנוע קונפליקטים בין שמות משתנים פונקציות וקלאסים.
 

the new L

New member
אם לפונקציות הללו

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

rubens1

New member
האמנם?

כפי שאמרתי, כבר יש לי class בשם IpAddr, אני באמת גם רוצה namespace כזה? ומתי אני מחפש פונקציה בIpAddr, ומתי אני מחפש אותה בNamespace IpAddress? ומה אם כל הקטע הזה של הIpAddr נכנס בתוך Namespace הרבה יותר גדול בשם Communication? ומה אם מדובר בפונקציה סטטית בודדת שקשורה לכתובות IP(לדוגמה: MakeMask, שמקבל מספר בין 0 ל31, ומחזיר subnet mask שדלוקים בו הביטים המתאימים?), האם תשים אותה בnamespace בנפרד? כפונקציה גלובלית? לא קשה לעשות Abuse לדברים שC++ מציעה. להשתמש בNamespaces לאיגוד פונקציות זה אחד מהדרכים.
 

the new L

New member
שוב

אם יש לך מחלקה שחלק מהפונקציות בהקשר שלה לא בהכרח משפיעות על איברי המחלקה וגם לא מחזירות אותה זה לגיטימי לחלוטין (רק תדאג להצהיר כמובן שהן const....). לעומת זאת, בדוגמה של אוסף פונקציות כמו sin, cos, ln ושלל פונקציות מתמטיות אחרות, אין שום סיבה בעולם לייצג לפונקציות הללו מחלקה, פשוט כי אין כאן שום אובייקט, ולכן זה גם לא הגיוני לעשות אותן פונקציות סטטיות. במקרה כזה עדיף להשתמש ב namespace.
 
אבל static זה יותר חזק מ-const

זה לא רק אומר שאתה לא משנה את המשתנים - זה אומר שאתה גם לא משתמש בהם. ההחלטה אם מתודה או משתנה מסויים כן יופיעו או לא יופיעו במחלקה מסויימת צריכה להקבע לפי המטרה של המחלקה והמתודות ולא לפי דרך-הפעולה שלהם. לא יתכן שהקביעה אם מתודה כן צריכה להיות חלק ממחלקה או לא תקבע רק בגלל שהיא משנה משתנה פנימי של אובייקט או משתמשת בו. המתודה שם - כי בשלב ה-design החלטת שאתה צריך אותה כחלק מהמחלקה. העובדה שאתה יכוללהוציא אותה החוצה, לא אומרת שזה נכון לעשות את זה.
 
אני ממש לא מסכים.(+דוגמה)../images/Emo26.gif

זו דוגמה מובהקת לשימוש במחלקה. אולי בנוסף שימוש ב-namespace - אבל זה ממש לא הפתרון כאן. תעזוב את העובדה שיש שפות רבות ללא namespace, אבל אני אתן לך דוגמה מהדבר האחרון שיצא לי לתכנת: בניתי מחלקה שאחראית על תרגום מפורמט אחד לשני. בעקרון המחלקה מקבלת reference לקובץ (למעשה ל-stream-ים - in ו-out) ויש לה מתודות תרגום. מתודה אחת שמתרגמת עד שנתקלת ב-EOF, מתודה אחת לתרגום פיסקה, משפט, מילה, אות... חלק מהמתודות תלויות באובייקט (נניח - כאלה שמשתמשות ב-streams או כאלה שמשתמשות באובייקטי-מיפוי שמהווים חלק מהאובייקט עצמו), אבל חלק מהמתודות פשוט לא משתמשות בשום מידע של האובייקט הספציפי ומסוגלות לתרגם עצמאית עפ"י הארגומנטים שמועברים להן). עכשיו... ברורים פה מאוד 2 דברים:
מקומן של המתודות הוא בתוך המחלקה. לוגית - הן חלק מקבוצת פעולות עם מטרה דומה, וזה ברור ש"לעקור" אותן מהמחלקה הזו תהיה שגיאת design.
אפשר להשאיר אותן ללא הגדרת static, אבל שוב - זו תהיה שגיאה סגנונית! אני כמתכנת צריך לשים כאן הצהרת-כוונות: "המתודה הזו לא מתעסקת לך עם האובייקט!"
 

the new L

New member
שוב אני אומר

במקרה שיש לך כבר מחלקה לאובייקט מסוים ואתה רוצה להוסיף פונקציות שקשורות לוגית, גם אם הן לא תלויות בנתונים שלו ישירות. א-ב-ל כשיש לך אוסף של פונקציות שקשורות לוגית שאין לך שום אובייקט במערכת שמתקשר אליהם אז כדאי להשתמש ב NAMESPACE.
 
../images/Emo35.gif כן נכון... ../images/Emo4.gif

קח לדוגמה את המחלקה Math ב-Java... היא כוללת פונקציות רבות (sin, cos, abs וכו') שעושות פעולות מסויימות - אבל התוצאה תלוייה רק בפרמטרים של המתודה ולא במשתנים של המחלקה. מבחינת ה-Design יש הצדקה לזה במקרים שאתה רוצה לאגד מתודות עם פונקציונליות דומה תחת מחלקה אחת (כמו בדוגמה של ה-Math).
 

the new L

New member
ושוב

למה זאת צריכה להיות מחלקה? מחלקה היא אבסטרקציה לטיפוס נתונים כלשהו. אין שום קשר לזה לבין טיפוס נתונים תשתמשו ב NAMESPACES!
 

ChipsMan

New member
כל זה טוב ויפה..

אבל בג'אווה אי אפשר להגדיר פונקציה סתם ככה. היא חייבת להיות שייכת למחלקה (סטטית או לא סטטית).
 

the new L

New member
בjava

אולי כן, אני לא יודע מספיק java לצערי... אבל ב c++ אין שום סיבה לעשות זאת
 
למעלה