As a number of you might know, I have been tutoring programming subjects at my old university for a number of years now. Both C# and VB.NET and the one common theme i’ve seen in these classes is that despite having completed a mandatory object-oriented programming subject, a large proportion of students just don’t get OO. Furthermore, most of them have no real idea of how to solve a programming problem other than a very heavy, top-down method:

  1. Students are given a programming assignment to solve, and 5 weeks to complete it
  2. They look at problem at the wholistic level just to try and understand the problem
  3. Start designing a UI and use all the wonderful draggy-droppy components on their forms
  4. Spend 2 weeks tweaking their UI colours and text box alignments.
  5. Spend 1 week hacking together some code so that their UI starts to interact
  6. Spend 1 week tweaking more UI elements
  7. Realise there’s only 1 week left and they are missing 30% of the functionality
  8. Panic, ask for extensions, submit the assignment late, or all of those together.

After seeing this pattern over and over, I’ve tried different ways to address the problem in my classes. The first thing I tried was to verbally (and written in the student forums) express my sentiments that students should focus less on their UI upfront and try to make sure they have basic UI completeness first, all of the functionality implemented and finally come back to polish the UI. After all, I was seeing a great number of assignments come through with functionality either untested, totally broken or just altogether missing. Sadly my words seemed to fall upon deaf ears, and the quality of assignments were not up to the standard I was expecting.

Tackling this problem differently, last year I thought I’d try and introduce the concept of unit-testing, TDD and told them to think less about the upfront-design and instead focus on testing individual components of their system independently and build up to a solution. At the time, it seemed like a lot of students were receptive to the idea of unit-testing and test-upfront, but when the assignments came down, it looked like they just fell back into old habits and the quality of assignments seemed (on the whole) not much different to previous semesters’. After talking to some of them, I suspect the problem was that it became too difficult for them to manage this new “style” of writing their programs and keep up on top of their other coursework. The quickest and dirtiest appeared to work, and the mentality that this was purely just another assignment for the sake of passing uni seemed clearer than ever. I’m guilty of this attitude too, as when I was in uni it was more of a concern for me to make sure I completed the assignment as quickly as possible so I could spend quality time on other activities. The problem with the unit-test/TDD approach was that it offers little to a student in a reward system. Unit-tested software takes longer to write than it’s direct-implementation counterpart. This pays off in the long-run, but when your “long-run” is only as long as a 6 month semester, then why investing extra time? It’s a classic ROI question. What I needed was a way to motivate students to improve the quality of their code, and without the seemingly large overhead of the automated tests.

This semester i’ve shaken things up once again, and have dropped the unit-testing/TDD mantra. Instead, i’m focusing *heavily* on problem decomposition, units of work, single responsibility and class separation. If unit-testing doesn’t drive students to think about their application functionality upfront, then hopefully teaching them a way to make a large problem seem easily palatable will motivate them to start thinking code-first instead of UI-first. Introduction to the concept of having one class per file seemed quite foreign and unnecessary when I discussed it in our first class last week. That didn’t fill me with confidence. Despite that, i committed to persisting with this trend, and re-enforced the importance of responsibility separation under the guise of making code easier to understand, but more importantly giving the students a method for decomposing a problem and forming a solution. This I think has been the key, because receptiveness to the idea suddenly picked up when I demonstrated building a simple Guess The Number game using a number of small, discrete components. They saw what at first appeared to be a task far too large for a 90 minute class, but by identifying single functions (like “ask the user to guess a number” and “determine if the user guessed too high”) and tackling them one-by-one we produced a solution, and it’s final composition was easy to follow. #win.

I’d also changed my presentation style and was more boisterous than normal. (for anyone who knows me in person, this would be pretty intense). My theory was that if I captured their attention, it would provoke them to treat my class differently to any of their others. After all, if i’m putting the effort in, they would reciprocate, wouldn’t they? Well i’m pleased to say that after 2 weeks (yes it’s early days still) i’ve had more students hang around for the full class than before and most importantly, when i’ve run overtime nearly 70% of my students are staying back (up to an hour – 10pm at night) to ask questions and learn more.

It still awaits to be proven whether this approach makes a difference with their assignments, but certainly I’ve seen a rather large improvement in the participation of students. I’m attributing this to a combination of making the classes more entertaining, and slicing the content so it’s easily digested. Historically this has been pretty bad at university level. Hopefully this time i’ve hit a winning formula.

This week, I hit an interesting problem which I don’t feel like was solved in the best possible way. The problem was that we needed to filter a list of objects based on some known criteria. Testing the specification is pretty important as there are a series of and’ed negating conditions (eg: IF this AND NOT that AND NOT the other etc…), in total about 5 unique criteria for the one filter.

Ordinarily this kind of implementation would lend itself nicely to the Specification Pattern given that all information required to determine if the specification is satisfied exists on the object member being passed in at the time of evaluation. In my case, however, I had 3 conditions that the object being evaluated must not exist in 3 different lists. To give you an example the object under evaluation is a model, and this step of filtering is part of a much larger process involving running the model through a recursive algorithm. At each step of the algorithm, the model object could have

  • Run through the algorithm succesfully
  • Been aborted during execution of the algorithm
  • Still awaiting to be executed through the algorithm

These three states are tracked by keeping 3 lists – one for each criteria. The filter that I was working on had to filter based on whether the model under evaluation was NOT in those three lists. I realise the wordiness of me explaining this doesn’t really clear the air, so lets look at some code (with relevant types changed).

This is my model:

    public class User
    {
       public bool Enabled { get; set; }
       public string Name { get; set; }
       public UserType TypeOfUser { get; set; }
    }

The code which uses my filter looks something like this. This guy will be called recursively based on the result that gets returned from here. In this case, i’m building the allValidUsersFilter.

public class ReplacementUserFinder
{
        ...ctor...fields...etc

        public User FindReplacementUser(User userToReplace, IList<User> allPossibleUsers, IList<User> usersStillToBeEvaluated, IList<User> usersAlreadyEvaluated, IList<User> usersAbortedDuringEvaluation)
        {
            var validUsers = _allValidUsersFilter.Filter(allPossibleUsers, usersStillToBeEvaluated, usersAlreadyEvaluated, usersAbortedDuringEvaluation);
            var replacementUser = _bestReplacementCandidateFinder.Find(validUsers, userToReplace);

            return replacementUser;
        }
}

and the interface for the AllValidUsersFilter – it’s purpose is to filter the list of all users to a list of potential candidates given the list of all users:

        public IList<User> Filter(IList<User> allpossibleUsers, IList<User> usersStillToBeEvaluated, IList<User> usersAlreadyEvaluated, IList<User> usersAbortedDuringEvaluation)
        {
            return allpossibleUsers.Where(x => 
                _isUserEnabledSpecification.IsSatisfiedBy(x) &&
                _isOverseasUserSpecification.IsSatisfiedBy(x) &&
                    !_isUserStillToBeEvaluatedSpecification.IsSatisfiedBy(x, usersStillToBeEvaluated) &&
                    !_isUserAlreadyEvaluatedSpecification.IsSatisfiedBy(x, usersAlreadyEvaluated) &&
                    !_isUserAbortedDuringEvaluationSpecification.IsSatisfiedBy(x, usersAbortedDuringEvaluation)
            ).ToList();
        }

The specification instances here are being ctor injected into my filter’s instance so that I can use a behavioural style assertion to check that the specification is invoked correctly by the filter.

The IsUserEnabledSpecification, and IsOverseasUserSpecification just use the well-known ISpecification interface pattern, but in order to evaluate the the other three, I had to create an IListSpecification and it feels somehow unsatisfying because the only thing different between them is that I have to pass in the list to the IsSatisfiedBy methods.

I’m not happy with this result, and we went through several different options before settling on this one purely just so we could move forward, and come back to address this later.

Hoping someone out there might have some suggestions…After writing this post, i’ve come up with another idea which would probably be cleaner…need to try it out.