Sunday, February 27, 2011

Dear vividwireless from a want to be customer

Earlier today I sent this email to vividwireless and I will be interested to see what their response is.  I have posted it hear so that others can think about it and comment if they like.

Dear vividwireless,

First of all let me start by saying that your product offering is very tempting and you appear to offer some excellent services. The only sticking point for me is the credit expiry for your prepaid offering. Let me explain:

I have excellent ADSL2 broadband at home with 150GBs of download per month, my house is also outside of your coverage area so even if the speed of your service was better than my home line I couldn’t change over (if the speed was just as good and I had coverage your unlimited plan would be extremely tempting).

All of that to say that vividwireless would not be my primary connection, however I have to do a bit of travel for work and quite often my travels take me to places that you do have coverage in. When I am staying at hotels it would be very handy for me to have one of your wifi hotspots with me. The trouble is I also sometimes travel in areas where you don’t have coverage and for those places I use a Telstra Next G USB modem. Telstra have coverage in pretty much all of the places you do and a whole lot more to boot. However you have a better connection so when I am in an area you do service I would prefer to use your connection. This brings me to the dilemma. If I buy prepaid credit from you it will most likely expire before I use it all. I understand how that is good for you, but it isn’t good for me.

At the moment I purchase $150 of credit from Telstra which lasts for 365 days. This means I don’t have to worry too much about wasting half of my credit due to it expiring on me before I use it all. If I purchase $150 of credit from you it only lasts 180 days so there is a high chance that I will not have used it all before it expires as I don’t need it the majority of the time. Even if recharging before it expires will extend the time on my credit you are essentially asking me to pay $25 per month for something I don’t use all that often, but would like to use when I need to.

If you removed the expiry from your credit or at the very least made it last for a year no matter how much I recharge with, then I would sign up right now, but as it is I will just stick with Telstra. So instead of you getting some of the money I give to them you will get none of it as I can’t afford the extra $25 a month for something I might not use very much. I imagine that I am not the only one in this situation and that by changing things you could make that a key selling point and appeal to larger market.

I think you guys are doing very well so far and are offering an excellent service (from the feedback I have heard from friends) and are breathing some fresh air into the stuffy telecommunications sector, but I think you can do even better. Think outside the box a little more and ditch the credit expiry and you will remove all reasons for someone not to buy your product.

Cheers,

Caleb Vear

Saturday, February 19, 2011

Put your behaviour where it belongs

This past week I have been working on a feature which allows the application to record the net weight of a various loads on a shipment.  There are of course certain rules which control whether a weight can be accepted or not and other side affects to accepting a weight, such as setting the date and time the weight was accepted.  All of this should of course be controlled by my domain classes, but how often have you seen code that looks something like this:

I must confess I have been guilty of writing code like that my self, but I have learned a lot since then and I now know that this can be done better.  Too often we fall into the trap of making our domain objects just a place to hold our data.  If we do this we wind up having our core business logic and behaviours strewn all over our application.  More and more I tend to favour having private or protected setters for all my properties.  Then the only way to make changes is by calling methods which model the actions that the users actually want to perform.  In my shipping example they are accepting the weight, they aren’t just setting it.  Accepting the weight is a core business concept and it has rules which apply.  My code now looks more like this instead, which in my opinion is a vast improvement:

Your methods for changing domain states should be verbs that the business would use to describe the action that is actually taking place.  Going back to my shipping example a Weight is made up of multiple Weighs.  This is because sometimes a truck is too long to fit on a weighbridge so they need multiple readings.  They describe the process as capturing a weigh, so my method is called CaptureWeigh(decimal reading, CaptureType captureType).  There are rules when capturing a weigh which are applied in that method.  Typically though a lot of code would just add the reading to a collection provided through a property on the Weight class, but that removes the chance to have the business behaviour captured in the object that represents it in your model.
When modelling your domain this way you will find that nearly all of your collections shouldn’t be exposed as IList<T> because you want to control what happens when you add something to them.  Rather than exposing IList<T> use IEnumerable<T>.  If you need to get the count you can just use the Count() extension method, if the instance you call Count() on is an IList then it will actually just return straight away without looping through the entire sequence.  I still return the underlying IList<T> from my IEnumerable<T> property even though I don’t want people to modify it.  I realise that that means they can cast it and then make changes, but the fact that I am IEnumerable<T> means they should know that isn’t a supported scenario.  If they want to ignore that and muck with it anyway then that is their problem.  I have seen people advocate wrapping the underlying list in a ReadOnlyCollection<T> instance to prevent modification, but I feel this is overkill.  After all at the end of the day I can’t stop people from accessing the list anyway as they can always use reflection and if they are going to use things in ways that the interface clearly shows isn’t supported then good luck to them and if it blows up in their faces that is their problem!