Saturday, April 30, 2011

Why agile software development is like teenage sex

Alexandre de Pellegrin writes: 

Today, Romain Gauthier (OCTO Technology, for the moment) sent me a funny post on Agile development. I really like Agile methods but it's so funny that I had to paste it here :


Why is agile software development like teenage sex?
  • It's on everyone's mind all the time.
  • Everyone is talking about it all the time.
  • Everyone thinks everyone else is doing it.
  • Almost no one is really doing it.
The few who are doing it are:
  • doing it poorly
  • hopeful it will be better next time
  • not practicing it safely

Source:
http://javacolors.blogspot.com/2009/02/why-is-agile-software-development-like.html

Tuesday, April 26, 2011

The need for transparency in software development

David Cooksey talks about the Agile principle of transparency specifically in software development.

http://blog.thycoticsolutions.com/2011/04/14/the-agile-virtue-of-transparency/

Saturday, April 23, 2011

Agile Development Principles To Live By

I'm currently reading an excellent book by Robert Martin (aka Uncle Bob) Agile Principles Patterns and Practises in C# (Prentice Hall).  I highly recommend it.
There is a fantastic list of agile principles in chapter 1, here's my synopsis of Robert's list.


  1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
    The smaller the deliverable of software the higher the quality and the less risk of non-delivery.  The more often you can deliver the higher the overall quality. All deliverables are production quality code.
  2. Welcome changing requirements, even late in the development. Agile processes harness change for the customer's competitive advantage. Embrace change, change is good, it demonstrates we have learnt more about the customer's needs. An agile development team should focus on software the is easy to change and maintain, simplifying the adaptive process. In my opinion I would also add to this, communicate the cost of change effectively to stakeholders as well; change does cost and whimsical change should be transparent and visible.
  3. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter time scale. Each delivery should satisfy some customer need.
  4. Business people and developers must work together daily throughout the project. In order to be agile there must be frequent interaction and assessment. A software project is not a fire and forget weapon.
  5. Build projects around motivated individuals. Give them the environment and support they need and trust them to get the job done. People are always the most important factor in any software project, everything else is secondary and will not compensate for the wrong people on a project.
  6. The most efficient and effective form of conveying information to and within a team is face-to-face conversation. Speech is a far richer and more concise form of communication over written forms, more information is imparted more quickly and with more detail. Documentation should be created incrementally, but only when NEEDED.
  7. Working software is the primary measure of progress. The project is 30% done when 30% of all features needed are finished and delivered.
  8. Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.  It is not a 100metre sprint, its more like a marathon. Care should be taken not to over commit.
  9. Continuous attention to technical excellence and good design enhances agility. High quality is the key to speed, badly written code generally leads to a do-over.  All team members must believe in and be committed to high quality and excellence. They do not create messes that they promise to fix next month.
  10. Simplicity - the art of maximising the amount of work not done is essential.  Take the simplest path that is consistent with the team and project goals. They do not put a lot of importance on solving tomorrow's problems, nor do they try and defend against them today. Rather focus on writing clear quality code that is easy to change.
  11. The best architecture, requirements, and design emerges from self organising teams. An agile team is a self organising team. Responsibilities should not be handed out, rather let the team decide and come to a consensus on decisions or let them choose who is best able to make these decisions if they feel they cannot contribute.  All team members should feel they have influence over decisions made.
  12. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behaviour accordingly. The agile team knows that its environment is constantly changes and the best processes from yesterday may not still be best.

This post is meant to be a quick reference of valuable Agile information.
References:

How to show a dialog in MVVM

In Mvvm you do not want direct references from your controllers (aka View-Models, I find it easier to call them controllers for simplicity).  This means you don't want code that specifically calls Window.Show or MessageBox.Show.  The reason is basically two-fold:

  1. First you will be unable to unit test the controller.  Message-boxes or Dialogs popping open will halt the test.
  2. If you decide to share some code with another project that uses a different UI technology, then not following Mvvm explicitly will prevent this. Also common is stakeholders changing their minds.
The solution is to make use of an Inversion of Control container (aka factory).



Message Box Usage

Message boxes pose a problem for unit testing because when open they block the thread from completing, meaning user intervention is required to continue a test. This is not acceptable. To circumvent this, MessageBox use can be accessed via an interface.

private IMessageBoxService backingMessageBoxService;
public IMessageBoxService MessageBox {
    get {
        return this.backingMessageBoxService ?? (this.backingMessageBoxService = new WpfMessageBoxService());
        }

        private set {
            // Provided for testing
            this.backingMessageBoxService = value;
        }
    }
}



The above code works in production, but during testing a mock will need to be injected into the MessageBox property.

        [Test(Description = "The save action should trigger a message box")]
        [Timeout(500)]
        public void SuccessfulSaveMessage() {
            var controller = new FormController(new ContactDataServiceStub());
            var accessor = new FormController_Accessor(controller);
            var messageBoxMock = new MessageBoxServiceMock();
            accessor.MessageBox = messageBoxMock;
 
            // Click the save button in the same way the View xaml would in production.
            controller.SaveCommand.Execute(controller.CurrentContact);
 
            Assert.IsTrue(messageBoxMock.WasShowCalled);
        }


public interface IGlassDemoDialog {
    event EventHandler Closed;
    void Show();
}

And from within your controller you can get a reference to the dialog through the use of an object factory (or using an interfaced property shown previously in this document).

var glassDialog = ObjectFactory.Container.GetInstance<IGlassDemoDialog>();
glassDialog.Show();

This of course assumes you have a registration with the object factory either in the app.config or in startup.

ObjectFactory.Initialize(init => {
    // Other config lines here
    init.For<IGlassDemoDialog>().Use<WpfGlassWindowDemo>();
});

Finally, your custom interface must be implemented by your View.
public partial class WpfGlassWindowDemo : Window, IGlassDemoDialog { }


[Test]
public void ShowGlassWindowTest() {
    var controller = new RighthandController();
    var mockRepository = new MockRepository();  // Rhino Mock
    var dialogMock = mockRepository.StrictMock<IGlassDemoDialog>();
    dialogMock.Expect(dialog => dialog.Show());
    mockRepository.ReplayAll();  // Prepare mocks.
    ObjectFactory.Initialize(init => {
        init.For<IGlassDemoDialog>().Use(dialogMock);
    });
    Assert.IsTrue(controller.GlassCommand.CanExecute(null));
    controller.GlassCommand.Execute(null);
    mockRepository.VerifyAll(); // Guarantee all mocks were used appropriately.