יום שלישי, 21 במאי 2013

Code smells - קוד מסריח

כולנו עושים refactoring לקוד שכתבנו (מקווה), חלקנו מבצעים code review.
יש כמה סימנים לזיהוי מקומות ״מסריחים" שאנחנו צריכים לטפל בהם (code smell) ולהלן העיקריים שבהם:

  1. הערות-צריכות לתאר ״למה״ ולא ״מה״. ה״מה״ צריך להיות מובן משמות המשתנים והפונקציות.
  2. פונקציות ארוכות - פונקציות קצרות יותר קל להבין, לקרוא, לתקן במידת הצורך. פונקציה אחראית על פעולה לוגית אחת (תפקיד אחד). קצרו את הפונקציות בהתאם.
  3. מספר רב של פרמטרים - ככל שלפונקציה יש מספר רב של פרמטרים, כך היא הופכת למסובכת יותר. תגבילו את מספר הפרמטרים, או השתמשו באובייקט שמרכיב כמה פרמטרים.
  4. שכפול קוד - אל תחזרו על עצמכם. שכפול קוד הוא אחד הטעויות הכי גדולות..
  5. תנאים מורכבים - המנעו מקינונים ארוכים ככל האפשר. במיוחד כאשר יש אפשרות שהקינונים יגדלו עם הזמן. במידת הצורך השתמשו בתבניות העיצוב: decorator, strategy, state.
  6. שימוש בswitch - תקראו את הפוסט שלי "אני לא יודע מה זה switch״
  7. העברת בוליאני כמשתנה לפונקציה - מצביע שלפונקציה יותר מתפקיד אחד.
  8. מחלקות ארוכות - כמו פונקציות ארוכות, מחלקות ארוכות קשות לקריאה, הבנה, ותחזוקה. אם המחלקה ארוכה תבדקו אם היא מכילה יותר מדי תפקידים ואחריות. אם כן תפצלו את המחלקה למספר מחלקות קצרות.
  9. השם של הפונקציה מורכבת מה type - עדיף שהשם של הפונקציה לא יהיה מורכב מה type שהיא מחזירה. זה מכריח אותנו לשנות את שם הפונקציה אם נשנה את ה type שהיא מחזירה
  10. שמות משמעותיים לפונקציות - האם השם מתאר את מה שהפונקציה עושה? האם מישהו שלא מכיר מה הפונקציה עושה, יכול להבין מה היא עושה רק על פי השם?
  11. שמות קונסיסטנטים - תצמדו לסטנדרט מסויים בכתיבת שמות משתנים ופונקציות
  12. שימוש ב ref ו out - אם אתם צריכים שהפונקציה תחזיר יותר ממשתנה אחד השתמשו ב class members . אם אין קשר בין המשתנים החוזרים, אז הפונקציה מבצעת יותר מתפקיד אחד.
  13. קוד ללא שימוש - מוחקים קוד שאין בו שימוש. זו הסיבה שיש source control.
  14. להימנע מתכנון של משהו שאף פעם לא יקרה - תכתבו קוד שאמור לפתור את הבעיה של היום. ברוב המוחלט של המקרים, אין צורך בגנריות כאשר לא צריך.. זה מסבך את הקוד, ופחות קריא (אלא אם באמת יש דרישה לגנריות)
  15. פרמטרים ללא שימוש - המנעו מלכתוב אובייקטים עם פרמטרים שאף אחד לא משתמש בהם.
  16. מימוש interface זהה - אם יש שני מחלקות שזהות במרכיבים הפנימיים שלהם, אז שיממשו אותו interface 
  17. מחלקות נתונים - המנעו מכתיבת מחלקות שמכילות רק נתונים. מחלקות צריכות להכיל גם פונקציות שעובדות על הנתונים.
  18. הורשה לא רצויה - אם אתם יורשים ממחלקה כלשהי, אבל אין שום שימוש בפונקציונליות שההורשה מספקת אז כנראה שלא מתאימה פה הורשה.
  19. המעיטו בחשיפת מטודות - המחלקות צריכות להיות כמה שפחות חשופות. צריכה להיות סיבה ממש טובה אם יש מטודה שהיא public.
  20. מטודות שמשתמשות במחלקות אחרות - אם המטודה שכתבתם משתמשת באופן רציף בפונקציונליות של מחלקה אחרת, כנראה שמקומה במחלקה שהיא משתמשת בה, ולא מקומה הנוכחי. 
  21. מחלקות בשימוש מועט - כל מחלקה נוספת בפרויקט גורמת לקוד שלנו להיות יותר מורכב אם יש לנו מחלקה שלא עושה הרבה, אז בדקו אם אפשר לאחד אותה למחלקה אחרת
  22.  Shotgun surgery - כל שינוי קטן בקוד שלכם גורם לבעיות בכמה מחלקות אחרות? כנראה שיש לכם בעיה. תנסו לתקן את הקוד. 
  23. פנייה לכלי בצד שלישי - כשפונים לספק חיצוני (למשל oracle) תעטפו את הפנייה במחלקה דקה כלשהי, כי במידה ותשנו את הספק (למשל sql) אז נצטרך לתקן רק במקום אחד.
מבוסס על Smells to refactoring
תהנו!

יום שלישי, 14 במאי 2013

Integration Patterns catalog

בהמשך לפוסטים הקודמים שלי: Scatter-Gather ו Claim Check, החלטתי להציג תרשים שמצאתי, ובו מפורטים באופן די טוב את סוגי ה Integration Patterns. 
קיימות עוד תבניות עיצוב שלא מופיעות בתרשים. (עם הזמן מפתחים עוד..)

תבחנו את עצמכם כמה אתם מכירים:

 תהנו!

יום שבת, 11 במאי 2013

WPF - שימוש ב Converter

שימוש מאוד נפוץ ב WPF הוא שימוש ב Converter.
במידה ואנחנו רוצים לעשות Bind לשני Properties שאינם בעלות אותו ה Type אנחנו חייבים להשתמש ב converter.
לדוגמא: לעשות Bind בין אורך הטקסט שהוכנס לבין צבע פקד ה TextBox (נראה פתרון לדוגמא זו).


 אפשר לחשוב על עוד המון אפשרויות bind יותר מורכבות (למשל בין התכונה IsChecked של CheckBox לבין Visibility של תמונה כלשהי.

נראה את הדוגמא הבאה:

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



ניצור Class חדש, שהוא יהיה בעצם המחלקת Convertor שלנו. הוא יממש את IValueConverter.

יש 2 פונקציות. הראשונה ממירה מערך המקור לערך היעד (ואותה נממש). הפונקציה השניה ממירה מערך היעד לערך המקור. פונקציה זו רלוונטית רק כאשר מבצעים Binding בעל Mode מטיפוס TwoWay או OneWayToSource.


    class Converter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string text;
          
            text = System.Convert.ToString(value);


            if (text.Length < 4)
            {
                return Brushes.Red;
            }
            else
            { 
                return Brushes.Green;
            }
            
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

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

ה Xaml שלנו יראה כך:
    <Window x:Class="first_converters.WindowTest"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:first_converters"
        Title="WindowTest" Height="300" Width="300">
    <Window.Resources>
        <local:Converter x:Key="length_converter"/>
    </Window.Resources>
    <Grid>
        <TextBox Name="txt" HorizontalAlignment="Left" Height="23" Margin="86,122,0,0" 
                 TextWrapping="Wrap"  VerticalAlignment="Top" Width="120" 
                 Background="{Binding ElementName=txt,Path=Text,Converter={StaticResource length_converter}}"/>
    </Grid>
</Window>

מה אנחנו רואים כאן:

קודם כל נוסיף Resource ל Class שהרגע כתבנו ונגדיר לו Key.
וכעת נעשה Bind-מהטקסט ב TextBox אל הצבע של ה TextBox.

והתוצאה:





תהנו!

יום רביעי, 1 במאי 2013

Create different shape to my wpf page

כשאנחנו מפתחים ב WPF, אנחנו לא חייבים שהWindow (או ה Page) יהיו בעלי צורה בנאלית מרובעת:


ב WPF יש אפשרות ליצור את ה Window שלנו באיזה צורה שנרצה:

לצורך העניין יש לי תמונה של דמות אדם, ואני ארצה שה Window שלנו יהיה בצורה של הדמות. כמובן שיכלנו כל צורה (עיגול, מתומן, או כל צורה שנרצה..) :

האפליקציה הסופית שלנו תיראה כך: (האפליקציה שלנו זה הצורה של הבן-אדם. ה screenshot על רקע notepad)

 אז איך זה נראה ב XAML:

<Window x:Class="AmazingWindowDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" 
 WindowStyle="None" AllowsTransparency="True" Background="Transparent">
    <Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown_1">
        <Image HorizontalAlignment="Left" Height="255" Margin="139,68,0,0"
  VerticalAlignment="Top" Width="294" Source="man.png"/>
  <Button Content="Button" HorizontalAlignment="Left"/>
    </Grid>
</Window>

אז מה עשינו פה?
 החלק החשוב זה החלק של ההגדרה של AllowsTransparency,WindowStyle,Background. ואז פשוט ה window "עוטף" כל צורה או תמונה שתגררו לטופס(במקרה שלנו זה man.png)

חשוב לא לשכוח להירשם לevent של MouseLeftButtonDown כדי שהמשתמש יוכל להזיז את החלון..
המימוש של הפונקציה:
  private void Grid_MouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }

תהנו!