Archive

Archive for the ‘Patterns & Practices’ Category

Call it Use Case or call it User Story, I cant imagine life without it.

May 17th, 2009 Simon Segal No comments

The question as to what the differences between Use Cases and User Stories is something that comes up quite often and some people will argue that they both help to achieve the same thing. Further discussion on that I will defer to debate elsewhere.

Over the last few years I have been using what I feel is a combination of the two elements rolled into one. One of the common held notions about User Stories is that they consist of written text that describes a functional unit of the system. Use Cases also describe functional units of work, semantically expressed through the use of the UML. My personal experience has been that the functional requirements can be well captured, represented, worked from and estimated using both approaches combined into one single method. Let me explain by way of example, where a single use case is catalogued using the following templated documents.

Figure 1.0 – User Story

user_story_bdd_story

What figure 1.0 shows is that we have combined the concept of several different approaches to suit. The UML for me has always been a great visual way of describing a system to both business stakeholders and developers, the BDD story title mirrors the Use Case name (UML) and the BDD story maps nicely to the Agile concept of the paragraph of text that describes a User Story. Added to that I can include scenarios to test if I am using BDD and further to that we include the document shown here as figure 2.0, the stories ‘Detail Table’.

Figure 2.0 – User Story Detail Table

detail_table

The detail table I found some time ago somewhere on the web and I cant remember exactly where so my deepest apologies to the author (if you recognize it please let me know and I will update this post). Again some more context here but mainly for the developer however it’s certainly within the grasp of a business analyst. As far as estimation goes, I am an advocate of first up estimation using Case Points Estimation techniques and then factoring in subsequent estimation off velocity and burn down rates.

Share/Save/Bookmark

A Death to overly long methods – please I am begging you!!!!!

May 11th, 2009 Simon Segal 6 comments

If you happened here by accident or design it matters not, this is a plea to all who find it. The plea is simply this:

“stop writing methods or functions that are overly deep and long”.

Do we really need to be telling each other this anymore? Isn’t this on page 3 of Object Oriented Software Development Part 1? Furthermore this is not a problem that only exists amongst developers who never had a formal training and cut their teeth on VBA. No indeed, I see this all too often and from University taught full time developers. The amount of productive time lost in trying to understand code that follows this pattern drives me crazy and I don’t know about you but I suspect most people are like me and have great trouble in retaining this kind of mess in their heads:

while (some_condition)
{
    switch(some_arg)
    {
        case “arg1″
            if(another_bool)
            {
                //…….etc 
            }
            else
            {
                while(yet_another_condition)
                {
                    if(nest_some_more)
                    {
                        //…ect
                    }
                }
            }
            break;
        case “arg2″
            if(!another_bool)
            {
                //…….etc 
            }
            else
            {
                while(!yet_another_condition)
                {
                    if(!nest_some_more)
                    {
                        //…ect
                    }
                }
            }
            break;
        case “arg4″
            //more of the same;
            break;
        case “arg5″
            ////more of the same;
            break;
    }
    if (some_bool)
    {
        while(another_condition)
        {
            if(another_bool)
            {
                //…….etc
            }
            else
            {
                while(yet_another_condition)
                {
                    for(int i=0;i>10;i++)
                    {
                        if(oh_my_god_another_bool)
                        {
                            //….etc
                        }
                        else if(can_things_go_on_like_this)
                        {
                            //….etc
                        }
                        else
                        {
                            //….etc
                        }
                    }
                 }
            }
        }
    }
    else
        while(here_we_go_again_condition)
        {
            if(and_here_we_go_again_another_bool)
            {
                //…….etc
            }
            else
            {
                while(im_in_agony_now)
                {
                    for(int i=0;i>10;i++)
                    {
                        if(my_brain_explodes)
                        {
                            //….etc
                        }
                        else if(the_project_fails)
                        {
                            //….etc
                        }
                        else
                        {
                            //….etc
                        }
                    }
                    switch(some_arg)
                    {
                        case “arg1″
                            //etc;
                            break;
                        case “arg2″
                            //etc;
                            break;
                        case “arg4″
                            //etc;
                            break;
                        case “arg5″
                            //etc;
                            break;
                    }
                 }
            }
        }
    }
}

Now if you think this is too long then double it or triple it and then see how you feel? If your laughing by this stage then either you have never had to work with this kind of code or your laughter is a spontaneous reaction that is masking what might be better represented by tears, given that you have indeed fallen victim to this too many times. If on the other hand you recognise this as your handy work then pay attention to the message and STOP IT!

Lets face it, we have all been guilty of this at some stage and on likely more than one occasion but when recognised for the misdemeanour that it is, one should immediately do penance and mend one’s ways. So rather than merely announcing the message to cease this practice haste with, it would be remiss to let the moment pass without making some recommendations as to what to do as an alternative. There is bad design at work here: if we think of our methods in terms of behaviour then each method should implement one concise behaviour and if you want keep your concerns separated and observe the SOLID principles, then your classes or modules should be following the single responsibility principle. Long methods / functions usually try to express several concerns in one very crowded space, making the code hard to understand and progressively difficult to maintain - time to refactor!

Share/Save/Bookmark

Silverlight and Model View Presenter (is it a realistic option?)

January 6th, 2009 Simon Segal No comments

I am currently working on ‘Case In Point‘, a Silverlight application which is available online and if you want to know more about it and why I chose to build it, please check out this previous post. In more recent times I have moved beyond the layout / UI Design stage (the main point in building this app) and have just now moved into preparing the ground for structuring my approach to the Business Logic and Data Access and how I was going to affect loosely coupled layers.

My first instinct was to tackle the task by using the recently devised Model-View View-Model pattern however I chose not to go down that path because this applications primary objective was to provide a learning exercise in UI skills and ultimately I thought that implementing the Model View Presenter pattern in a Silverlight application would provide me a solid foundation to compare when I do finally try out MVVM.

Over the past couple of years I have become accustomed to using a home grown MVP Framework that was fully templated in Visual Studio and offered a lot of benefit in speed of use by cutting out a lot of the repetitive file creational stuff that such an approach requires. Using this templated framework meant that creating a ‘new item’ in Visual Studio would trigger the creation of the Model, View (user control, page, form etc) and Presenter, wiring their dependencies (via injection) together in the process. One of the benefits of this homegrown MVP framework was it’s ability to deal with what effectively handled two way Databinding between the views and the model, something that we now get from Silverlight for free, which gave me a chance to really see how MVP would benefit or from this aspect.

So far my standard MVP approach for Win Forms and Web Forms seems to sit equally as well with Silverlight so I am pleased that I can move forward quickly with completing this learning exercise, which as I have pointed out was completely about getting comfortable with Silverlight in respect to gaining familiarity with the new UI paradigm.

Setting up the Model View Presenter.

public partial class CaseInPoint : UserControl
{

    //The main UI View (control) that loads all the tabs views)
    public CaseInPoint()
    {
        InitializeComponent();

        //new up the model for the tabbed application
        PointInCaseProject model = new PointInCaseProject();

        //new up all the presenters
        CaseInPointPresenter mainPagePresenter =
            new CaseInPointPresenter(this, model);

        ProjectDetailPresenter projDetailsPresenter =
            new ProjectDetailPresenter(this.AppTabs.ctlProjectCalculator, model);

        FactorsPresenter factorPresenter =
            new FactorsPresenter(this.AppTabs.ctlFactorList, model);

        UserStoryPresenter storyPresenter =
            new UserStoryPresenter(this.AppTabs.ctlUserStoryView, model);

        ActorsPresenter actorsPresenter =
            new ActorsPresenter(this.AppTabs.ctlActorsView, model);
    }
}

The Presenter.

internal class ProjectDetailPresenter : IPresenter
{
    private ProjectDetailCalculator _view;
    private PointInCaseProject _model;
    private CaseInPoint _viewParentWindow;

    internal ProjectDetailCalculator View
    {
        get { return _view; }
        set { _view = value; }
    }

    internal PointInCaseProject Model
    {
        get { return _model; }
        set { _model = value; }
    }

    internal ProjectDetailPresenter(ProjectDetailCalculator view,
                                    PointInCaseProject model)
    {
        //set the view and model
        _view = view;
        _model = model;
        //wire up the events of the view and its parent window
        WireUpEventsOnInit();
        //do any initial data binding
        InitialBindUiToEntity();
    }
}

And finally the Model

[XmlRoot()]
internal class PointInCaseProject : INotifyPropertyChanged
{
    private ProjectDetails _details;
    private List<EnvironmentalFactor> _environmentalFactors;
    private List<TechnicalFactor> _technicalFactors;
    private List<UserStory> _userStories;
    private List<Actor> _actors;

    /// <summary>
    /// The list of User Stories contained
    /// within the point case estimate project.
    /// </summary>
    [XmlElement()]
    internal List<UserStory> UserStories
    {
        get { return _userStories; }
        set
        {
            NotifyPropertyChanged(“UserStories”);
            _userStories = value;
        }
    }

    /// <summary>
    /// The list of Technical Factors
    /// within the point case estimate project.
    /// </summary>
    [XmlElement()]
    internal List<TechnicalFactor> TechnicalFactors
    {
        get { return _technicalFactors; }
        set
        {
            NotifyPropertyChanged(“TechnicalFactors”);
            _technicalFactors = value;
        }
    }

    /// <summary>
    /// The list of Environmental Factors
    /// within the point case estimate project.
    /// </summary>
    [XmlElement()]
    internal List<EnvironmentalFactor> EnvironmentalFactors
    {
        get { return _environmentalFactors; }
        set
        {
            NotifyPropertyChanged(“EnvironmentalFactors”);
            _environmentalFactors = value;
        }
    }

    /// <summary>
    /// The list of Actors within the 
    /// point case estimate project.
    /// </summary>
    [XmlAnyElement()]
    internal List<Actor> Actors
    {
        get { return _actors; }
        set
        {
            NotifyPropertyChanged(“Actors”);
            _actors = value;
        }
    }

    /// <summary>
    /// The details of the 
    /// point case estimate project.
    /// </summary>
    [XmlElement()]
    internal ProjectDetails Details
    {
        get { return _details; }
        set
        {
            _details = value;
            NotifyPropertyChanged(“Details”);
        }
    }

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void Clear()
    {
        if (this._details != null) { this._details.Clear(); }
        if (this._actors != null) { this._actors.Clear(); }
        if (this._environmentalFactors != null)
        {
            this._environmentalFactors.Clear();
        }
        if (this._technicalFactors != null) { this._technicalFactors.Clear(); }
        if (this._userStories != null) { this._userStories.Clear(); }
    }
}

NOTE: This is not the entire code base and some things above have been left out or assumed, things such as the entities that are contained in generic<> lists in the model and all the subscribing handlers for view events that would be present in the presenters. At the end of the exercise I will follow up by implementing a small application using MVVM framework, putting me in a better position to discuss the differences and merits of both approaches. I have read some opinion that suggests that the Databinding abilities present in Silverlight and WPF are not equally as available to pre-exiting UI development frameworks such as MVC and MVP so I consider this is step one in putting that assertion to the test for my own sanity.

Of course a happy by-product of this exercise is getting a tool to manage my point case estimations for real world projects and in so doing I will be able to remove the dependence on the spreadsheet that currently manages this task for me. As it stands today, the project details tab has it’s data being persisted and I have decided to take a document centric approach to the persistence. Each project will save it’s estimation data in XML format locally in Isolated Storage and each file is saved as a .pce (point case estimate) file. I will post the Visual Studio solution when the project is complete.

Share/Save/Bookmark

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia