Chapter 2. Pair Programming

This is a chapter for you to follow if you have a partner to pair with. If you do not have someone with whom you can work through this chapter, go find someone. Recruit a friend, work colleague, or a fellow student.

This chapter provides a series of exercises that encourage you and your partner to take turns in typing the code and thinking about the problems. This chapter emphasizes the benefit of programming with a buddy and how much fun this type of development can be. It also shows you how business benefits can be gained from development in pairs and how you might best promote these ideas to your organization.

As discussed in Chapter 1, pair programming is the practice of developing all production code with two developers sitting at one machine. This goal of this practice is for developers to help each other create something far greater than one developer alone could do alone.

Pair programming may be the hardest of the XP techniques. It certainly raises the most concern among the software development community. As software developers, we are typically taught to program on our own. I expect that (like myself), the self-taught programmers have spent many hours on their own, playing with code and working out how to make some software do something. Even the education system tends not to encourage software to be developed by groups or teams, measuring success by the work of an individual.

However, as an average individual (which, of course, you and I are not!), my IQ is around 100. Surely if I work with someone else who is also average, our combinedIQ should be somewhat higher. It is unlikely that we can get close to 200 because much of our intelligence overlaps, but hopefully we could get to 130 or more. In Software for Your Head[1], the McCarthys explain the idea of a team IQ, with each member of the team contributing to the overall IQ of a team. Pair programming relies on the same premise, and the team size is two for the coding task being developed.

I’m Not Sitting with Him!

I have been astounded and astonished more than once to hear fully grown adults utter these words: “I’m not sitting with him.” It is almost as much as I can do sometimes to ask whether they think they are still in grade school. However, that would be unproductive.

The Professional Attitude

The reality of the modern workplace is that we might not connect with everyone as well as we might like. We will have to work with some folks who have bad breath, speak too loudly or too quietly, and so on. As professional software developers, we need to act in a professional manner and exhibit a professional attitude toward our colleagues.

Get With the Winning Approach

If we have a technique that enables us to deliver software that is better in some way (quicker to deliver, more robust and smaller), we should use it until we find a technique that creates more of what we want. In my opinion, this philosophy should be applied to more than just software development, but that’s a topic for another book.

It’s a Game

As the saying goes, “Time flies when you’re having fun.” I think this could easily be extended to “Time flies when you’re having fun developing software.” It always amazes me how quickly the day goes by when I am in programmer mode. I am sure that in part it is because I am enjoying what I am doing. I love writing code and developing software; to me it is like a puzzle game.

As a young kid learning to program, I had a good friend who was also keen to learn, and we would often sit together at my father’s Commodore computer and type in lines of code, suggesting ideas as we went and improving on each other’s code. It was a lot of fun, and we created some pretty cool little applications (at least, we thought they were).

Upon learning of pair programming, I realized that as kids, my friend and I had been pair programming, and that if it was fun then it should surely be a lot of fun now.

Exercise 2-1: Game to Teach Pair Programming

This game is based on another game called the Perfection Game, which can be found in Software for Your Head. You can play it with two or more people. To play this game, you need one PC with one keyboard, one mouse, .NET Framework development tools installed, enough chairs, and space for all developers to sit and see the screen. With more than two people, I suggest you use a projector so that all the participants can see what is going on.

There are two roles in this game: programmer and supporter. Each person takes turns to be the programmer, while everyone else takes the role of the supporter.

  1. The programmer declares what the function he is going to write will do. He states his intention. I suggest something small that can be completed in less than 5 minutes.

  2. When the programmer is finished, he declares he is done.

  3. Each supporter in turn grades the function from 0 to 10, with 10 being the highest value and 0 being the lowest. For every point less than 10 that is given, the supporter must come up with a way of making it a 10.

    1. The supporter then follows his grading with a statement of what he likes about the code as written.

    2. The supporter then states what it would take to get a 10.

  4. One of the supporters takes the role of the programmer, and the process begins again.

  5. After everyone has had one turn at being the programmer, you can repeat the cycle, but this time the programmer starts with the code that he or she wrote before and tries to improve it for a couple of minutes to raise the grade.

Here is an example round between two of the programmers in our eXtreme .NET team, Deepak and Sue.

Pointers for the supporter:

  • Keep the feedback positive. Say what you like and what it would take to get to 10. Do not say what you don’t like.

  • Don’t be personal. Keep your comments focused on the product, not on the programmer. Phrasing the statements is important. It is better to say, “I like the way the function uses the increment operator” rather than “I like the way you used the increment operator.”

  • Remember you are scoring the product, not the programmer.

Pointers for the programmer:

  • Remember, it is not personal. The supporter is scoring the code, not you.

  • Always remember to thank the supporter for the input. It is helping the product get better.

Exercise 2-2: Step-by-Step Exercise to Get a Feel for Pair Programming

In this exercise, you focus on the pair programming aspect and do not worry about the other practices. This exercise can be done without having read any of the other chapters in this book. The aim is to help the two of you get a feeling for writing code as a pair.

To do this exercise, you need one PC with one keyboard, one mouse, .NET Framework development tools installed, two chairs, enough space for both developers to sit in front of the PC and see the screen, and one copy of this exercise (i.e., this book).

Start off with one of you controlling the PC (the driver) and the other holding the exercise (the navigator). The navigator is going to guide the driver through developing the code. At certain points, you will swap roles. It is very important that you do swap at the specified times and no later. While you are in the role of navigator, try not to show your partner the code as it is written in the exercise. You should attempt to verbally communicate what needs to be done. You can draw diagrams and as a last resort read out the line of code to be typed. If at any point either of you feel unsure that you have done the correct thing, it is time to compile and test what you have done. You should be able to compile and run the program after nearly every step.

In keeping with the theme of pairing being fun, you are going to develop a screen saver together:

  1. Start off by setting up a Windows Forms application to work as a screen saver. Create a new C# Windows Forms application project called Extreme Screen Saver.

  2. Change the name of the created form class to SaverForm.

  3. Edit the constructor to take an integer parameter and store it in a member variable of the class called ScreenID.

    private int screenID;
    public SaverForm(int screen)
    {
        InitializeComponent();
        screenID = screen;
    }
    
  4. Edit the Main method to use parameters to determine how to run the application. This is how Windows launches a screen saver.

    It might help if you can draw a table for your partner (on a white board or a scrap of paper).

    Argument

    Meaning

    /c

    Display the config/settings screen

    /s

    Launch the screen saver

    /p

    Preview the screen saver

    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            // config
            if (args[0].ToLower().Trim().Substring(0,2) == "/c")
            {        }
            // saver
            else if (args[0].ToLower() == "/s")
            {        }
            // preview
            else if (args[0].ToLower() == "/p")
            {         }
        }
        else
        {         }
    }
    
  5. Create a static protected method in the SaverForm class called LaunchSaver. In this LaunchSaver method, add code to iterate through all the screens connected to the PC and create a new form to run in that screen.

    static protected void LaunchSaver()
    {
        for (int i = Screen.AllScreens.GetLowerBound(0);
            i <= Screen.AllScreens.GetUpperBound(0); i++)
        {
            System.Windows.Forms.Application.Run(new SaverForm(i));
        }
    }
    
  6. Back in the Main method, call this static method from the launch and default argument cases.

    static void Main(string[] args)
    {
        if (args.Length > 0)
        {
            if (args[0].ToLower().Trim().Substring(0,2) == "/c")
            {    }
            else if (args[0].ToLower() == "/s")
            {
                SaverForm.LaunchSaver();
            }
            else if (args[0].ToLower() == "/p")
            {    }
        }
        else
        {
            SaverForm.LaunchSaver();
        }
    }
    
  7. Compile and run the program. Close it, and then try renaming the created EXE file from eXtreme Screen Saver.exe to eXtreme Screen Saver.scr. You should be able to install this and run it as a screen saver.

  8. Swap roles.

  9. We will now set up the form to occupy the entire screen and respond to mouse and keyboard events to close down. In the design view for the Saver-Form, set the FormBorderStyle property to None.

  10. Create an event handler for the Load event on the form. This can be done by double-clicking the form in design view. In this method, we need to set the Bounds of the form to those of the screen, hide the cursor, and set the form to display on top of all the other forms.

    private void SaverForm_Load(object sender,
        System.EventArgs e)
    {
        Bounds = Screen.AllScreens[screenID].Bounds;
        Cursor.Hide();
        TopMost = true;
    }
    
  11. In this Load method, we can also add handler code for the mouse and keyboard events. We want to handle these events and decide whether we are going to end running the screen saver. Start by adding an event handler for the MouseMove event. Call this method SaverForm_MouseEvent. In Visual Studio.NET, you can type MouseMove += and then pressing the Tab key should generate the handler skeleton.

    private void SaverForm_Load(object sender,
        System.EventArgs e)
    {
        ...
        MouseMove +=new MouseEventHandler(SaverForm_MouseEvent);
    }
    

    When the application first runs, it will get the mouse location through a mouse move event, so the first time we get the event, we just need to trap the position of the mouse in a member variable. After that, if the mouse moves, we need to close the application.

    private Point initialMousePt;
    private void SaverForm_MouseEvent(object sender,
        MouseEventArgs e)
    {
        if (!initialMousePt.IsEmpty)
        {
            if (initialMousePt != new Point(e.X, e.Y))
                Close();
        }
        initialMousePt = new Point(e.X, e.Y);
    }
    
  12. We can use this same event handler for the mouse down event that occurs when a user clicks a mouse button. Add the method to the event in the Load method. Then change the MouseEvent method to also close the form when a click has occurred.

    private void SaverForm_Load(object sender,
        System.EventArgs e)
    {
        ...
        MouseMove +=new MouseEventHandler(SaverForm_MouseEvent);
        MouseDown +=new MouseEventHandler(SaverForm_MouseEvent);
    }
    
    private void SaverForm_MouseEvent(object sender,
        MouseEventArgs e)
    {
        if (!initialMousePt.IsEmpty)
        {
            if (initialMousePt != new Point(e.X, e.Y))
                Close();
            if (e.Clicks > 0)
                Close();
        }
        initialMousePt = new Point(e.X, e.Y);
    }
    
  13. Now let’s do the same with a handler for the KeyDown event.

    private void SaverForm_Load(object sender,
        System.EventArgs e)
    {
        ...
    
        KeyDown +=new KeyEventHandler(SaverForm_KeyDown);
    }
    
    private void SaverForm_KeyDown(object sender,
        KeyEventArgs e)
    {
        Close();
    }
    
  14. Compile and run the program. It is starting to work more like a screen saver. Rename the EXE file to an SCR file and test it. We now have a basic screen saver.

  15. Swap roles.

  16. The next thing to do is to add some drawing functionality so that the screen saver actually does something. We will start by adding a Paint event handler to the Form class. Again we can do this in the Form load method.

    private void SaverForm_Load(object sender,
        System.EventArgs e)
    {
        ...
        Paint +=new PaintEventHandler(SaverForm_Paint);
    }
    
    private void SaverForm_Paint(object sender,
        PaintEventArgs e)
    {
    }
    
  17. In the Paint event method, we will add some code to draw the text eXtreme .NET in the center of the screen. We will use the TranslateTransform method to shift the drawn text to the center of the screen.

    You need to add the System.Drawing.Drawing2D namespace to this class file because we need to use the MatrixOrder enumerated type from there.

    private void SaverForm_Paint(object sender,
        PaintEventArgs e)
    {
        Graphics gc = e.Graphics;
        Point screenCenter = new Point(
            (int)(gc.VisibleClipBounds.Width/2),
            (int)(gc.VisibleClipBounds.Height/2));
    
        gc.TranslateTransform(screenCenter.X,
            screenCenter.Y,
            MatrixOrder.Append);
    
        int fntSize = 12;
        Font fnt = new Font(FontFamily.GenericSansSerif,fntSize);
        Brush brsh = Brushes.Red;
        StringFormat format = new
            StringFormat(StringFormat.GenericTypographic);
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;
    
        SizeF size = gc.MeasureString("eXtreme .NET", fnt);
    
        RectangleF rect = new RectangleF(
            0 - size.Width/2,
            0 - size.Height/2,
            size.Width,
            size.Height);
    
        gc.DrawString("eXtreme .NET", fnt, brsh, rect, format);
    }
    
  18. Add a timer control to the form and use the timer event to redraw the screen so that we can add some animation to the text. You do that in the design view. The timer control can be dragged from the toolbox onto the form and then double-clicked to generate the event handler method. Make sure you set the Enabled property of the timer to true so that it raises the events.

  19. In the timer event handler, we will call Invalidate.

    private void timer1_Tick(object sender,
        System.EventArgs e)
    {
        Invalidate();
    }
    
  20. Next animate the text. We will make the text grow and shrink on the screen using the ScaleTransform method of the Graphics object. To do this, we need some class member variables to represent the current scale and the amount to change the scaling. We can manipulate these in the timer tick event.

    private float scale = 1;
    private float scaleChange = 0.1F;
    
    private void SaverForm_Paint(object sender,
        PaintEventArgs e)
    {
        Graphics gc = e.Graphics;
        Point screenCenter = new Point(
            (int)(gc.VisibleClipBounds.Width/2),
            (int)(gc.VisibleClipBounds.Height/2));
    
        gc.ScaleTransform(scale,
            scale, MatrixOrder.Append);
        gc.TranslateTransform(screenCenter.X,
            screenCenter.Y,
            MatrixOrder.Append);
        ...
    }
    
    private void timer1_Tick(object sender,
        System.EventArgs e)
    {
        scale+= scaleChange;
        if (scale < 1)
        {
            scaleChange = 0.1F;
        }
        if (scale > 20)
        {
            scaleChange = -0.1F;
        }
        Invalidate();
    }
    
  21. Compile and run the program. You may want to decrease the Interval property on the timer to make the animation more viewable.

  22. Swap roles.

  23. We will use some of the built-in double buffering provided by the .NET Framework to remove the screen flicker. We will also add some more movement to the text animation. Before we add the double buffer in the constructor of our Form class, we need to set the style of the form to use WMPaint, the UserPaint style, and DoubleBuffer.

    public SaverForm(int screen)
    {
        InitializeComponent();
        screenID = screen;
        this.SetStyle(
            ControlStyles.AllPaintingInWmPaint|
            ControlStyles.UserPaint|
            ControlStyles.DoubleBuffer, true);
    }
    
  24. Now let’s add rotation to the text animation so that it spins around as it grows and shrinks. We will use two class member variables to indicate the current angle of the text and the next amount by which to change the angle. We can vary this in our timer tick event method. In the Paint event method, we will use the RotateTransform method to rotate the text around the origin.

    private float angle = 0;
    private float angleChange = 5;
    
    private void SaverForm_Paint(object sender,
        PaintEventArgs e)
    {
        Graphics gc = e.Graphics;
    
        Point screenCenter = new Point(
            (int)(gc.VisibleClipBounds.Width/2),
            (int)(gc.VisibleClipBounds.Height/2));
    
        gc.RotateTransform(angle, MatrixOrder.Append);
        gc.ScaleTransform(scale,
            scale, MatrixOrder.Append);
        . . .
    }
    
    private void timer1_Tick(object sender,
        System.EventArgs e)
    {
        angle+=angleChange;
        scale+= scaleChange;
        if (scale < 1)
        {
            scaleChange = 0.1F;
            angleChange = 5F;
        }
        if (scale > 20)
        {
            scaleChange = -0.1F;
            angleChange = -5F;
        }
        Invalidate();
    }
    
  25. Compile and run the program. The animation should look much smoother. Try it as a screen saver by renaming the EXE file.

This exercise should have provided you with an understanding of how often you should swap roles and how important it is for both of you to be involved with the code being developed. Pairing is no fun if you are just watching someone else write code. It also has very little value if that is all that occurs during a pair-programming session.

Pair programming is about both developers being present and focused on the task at hand and both developers aiming to help make the code better.

Try It Together

You are now ready to try pairing on some code together. Remember, pair programming is a skill as much as learning to code is a skill. The more you do, the better at it you will become.

Exercise 2-3: Exercises for Two Developers to Work On Together

These following tasks are for you to work through together and try to develop the screen saver we developed further. During the exercise, make sure you swap roles often; I suggest that if you haven’t swapped for ten minutes, you should stop and swap roles.

  1. Extend the screen saver to display a preview.

    In the preceding exercise, you have created an entry point in the code that will get called when the program is run with the /p argument. Extend the code to draw the animation in the preview window provided.

    Hint: The second argument in the command-line arguments is a handle to a window (hWnd) in which to draw the screen saver preview.

  2. Extend the screen saver to display a settings box.

    Carry on from the screen saver exercise again, and this time add functionality to display a configuration dialog box so that the user can alter the settings on the screen saver. The entry point is already created in the Main method when a /c parameter is passed to the application.

    The settings to be altered are the speed of the animation, the angle of rotation, the text color, and finally the ability to customize the text.

Conclusion

As mentioned throughout this chapter, pair programming is a skill that needs to be learned. Some practices covered in this chapter are intended to help you become a better partner when pairing. The perfection game can teach us how to help each other create a better product in a positive way. Keeping the conversation going during the pairing session is critical. The communication that occurs while pairing is what enables us to create something better than we would have done on our own.

As a closing thought, I want to share with you the fact that the more I pair program, the more I realize what I don’t know. It is the best way I have found of learning new skills from another developer. Whenever I have an opportunity to pair program with a developer, I do so. I have learned as much from junior developers as I have from experts. With the combined intelligence and experience of two developers at work on the same code, this is the closest thing to having a genius write every line of code.

The next chapter explores another practice we can use to help us toward genius a practice that helps us to solve big problems.

1.

McCarthy, Jim. Michele McCarthy. Software For Your Head. Upper Saddle River, New Jersey:Addison-Wesley Professional, 2001.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.164.210