Sarah Taraporewalla's Technical Ramblings

Coding Tip #42: Turning Enums Into Classes

| Comments

In Coding Tip #27 I explained how I rarely like to use booleans to represent states, and prefer to use an enum. Now that I have all nice little enums everywhere, another pattern that I see emerge is that I want more from my enum than just a value: perhaps other values associated with it, or actual behaviour. These enums then get converted into fully-fledged objects (ie classes) in the system with a very simple refactor.

So, the code started with:

1
private bool hasVehicle;

then, by following Coding Tip #27, went to:

1
2
3
4
5
6
7
private Vehicle theVehicle;
public enum Vehicle
{
    Car,
    MotorBike,
    PeopleMover
}

and now can turn into:

1
2
3
4
5
6
7
8
9
10
11
12
13
private Vehicle theVehicle;
public class Vehicle
{
    public static Vehicle Car = new Vehicle("Car");
    public static Vehicle MotorBike = new Vehicle("MotorBike");
    public static Vehicle PeopleMover = new Vehicle("PeopleMover");

    private Vehicle(string name)
    {
        this.name = name
    }
    private string name;
}

so my objects are all setup to add additional functionality:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private Vehicle theVehicle;
...
theVehicle.WillSeatAPartyOf(4);
...
public class Vehicle
{
    public static Vehicle Car = new Vehicle("Car", 5);
    public static Vehicle MotorBike = new Vehicle("MotorBike", 2);
    public static Vehicle PeopleMover = new Vehicle("PeopleMover", 8);

    private Vehicle(string name, int passengerLimit)
    {
        this.name = name
        this.passengerLimit = passengerLimit;
    }
    private string name;
    private int passengerLimit;

    public bool WillSeatAPartyOf(int numberOfPassengers)
    {
        return numberOfPassengers =< passengerLimit;
    }
}

I debate whether the class should contain the name or the index, usually I use the name; you can use both. Obviously if someone was now relying on the enum order, you would need to give it the index. Another advantage of this is because the constructor is private, you know that there are a definitive list of representations for it.

I don’t usually use class straight away. Indeed, I usually take bets to see how long it will stay an enum - sometimes the refactor is immediate, other times it remains an enum.

Canned, Stubbed and Mocked Fake Objects

| Comments

I had a very interesting discussion with Jen Smith today about the differences in approach to faking objects during testing. As a result, I am finally putting down my thoughts on the matter.

Canned Objects

Canned objects are fantastic to use in situations where you want an object to respond with a predefined value or you don’t care what the response is as it doesn’t directly effect your test. It responds with the same value no matter how many times I call it. I use these objects most extensibly in my testing, especially for repositories. I only have one canned fake object per real object, except when I have services which, eg do validation; in this case, I create NegativeValidationService and PositiveValidationService objects to help readability of tests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CannedBookRepository : IBookRepository
{
    private IBook book;
    public CannedBookRepository(IBook book)
    {
        this.book = book;
    }
    public CannedBookRepository() : this(new BookBuilder()) {}

    public IBook Find(IKey bookKey)
    {
        return this.book;
    }
    public void Save(IBook book) {}
}

Stubbed objects

Stubbed objects are fake representations of their real counterparts, and as such will tend to emulate their behaviour. The main difference, however, is that they do not talk to expensive services, eg database connections. I use stubbed objects mainly when I need my fake object to reply in different ways for different inputs, or when testing that I can put an object into a repository and will access an identical version of it. Again, generally I have at most one per real object; I usually don’t use them.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class StubbedBookRepository : IBookRepository
{
    private IList books = new List;

    public IBook Find(IKey bookKey)
    {
        return this.books.Find(book => book.Key.Equals(bookKey));
    }
    public void Save(IBook book)
    {
        this.books.Add(book);
    }
}

Mocked Objects

Mocked objects make use of existing mocking libraries, such as Mockito, Rhino mocks or mocha and are used mainly to test either that the correct method has been used for an API or when testing legacy code (ie when they have used static methods/classes and I cannot change that - TypeMock can do weird stuff with statics).

Why

The main reasons why I prefer these fake objects, as opposed to using a mocking library to stub certain methods are:

  • it is less lines of code in the test (only by declaration) - there are no setup, stub, replay/verify calls. All setup is done in the constructor
  • it is more maintainable - resharper can refactor it easily. Also if the methods are being refactored, eg changing a bool return type to an enum there is a single point of failure
  • it is easier to read (imho)
  • I don't have to worry about different syntax when creating real and fake objects - they are created in exactly the same manner. This also helps testing, as usually they are not the main concern of the test
  • once created, they are always there to be used
  • they help drive out design - if I find I have a fake object with many methods which throw the NotImplementedException, I can begin to ask "Are all these behaviours on the correct object?"

To summarize: canned fake objects are cool.

I Don't Believe in ORM Object as Your Domain Model

| Comments

I have been on a few projects now where we have used ORM libraries to help store our data (eg ActiveRecord for Rails, Hibernate (and it’s variants), Castle’s ActiveRecord for .Net). On these projects, we have used the domain models and the ORM models are the same.

The problem we faced with doing so is the same problems I think most people face : eventually, your domain wants to take your model in one direction, and your relational database wants to take it in another. Personally, I really like Domain Driven Design - I like my objects to be reflective of the domain - and I don’t really care about how the database stores them, or indexes or stuff like that (I seem to remember something about BNF back in uni), so I am more inclined to let my model move towards the domain; but I do understand that there are consequences in doing so when looking at how my data is accessed.

I have now come to the belief that there is value in having my domain models but equally having ORM models. More so, I have decided that (despite the perceived increase in classes) there is a true distinction between the two and should be implemented as two separate classes. You can see from my examples what I am talking about, but basically my domain model knows nothing about the ORM model and anyone (apart from the necessary repository) knows about it either. The ORM model is used by the repository of concern as a helpful tool for it to store to the database; it could equally be done using SQL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# The Domain model - yes there is more to it than that
class RegistrationForm

  def initialize(key)
    @key = key
    @name = ""
    @email = ""
  end
  ...
end
# The repository to find/save a registration
class RegistrationRepository

  def find(key)
    registration = find_registration(key)
    form = RegistrationForm.new
    return form unless registration
    update_form(form, registration)
  end

  def save(form)
    registration = find_registration(form[:key])
    registration = create_registration unless registration
    update_registration(registration, form)
    registration.save
  end

  private

    def find_registration(key)
      registration = Registration[:id => key]
     # This is the sequel equivalent of Registration.Find(key) in ActiveRecord
    end

    def create_registration
      registration = Registration.new
      registration
    end

    def update_form(form, registration)
      form.update(
        :key => registration.id,
        :name => registration.name,
        :email => registration.email)
      form
    end

    def update_registration(registration, form)
      registration.name = form[:name]
      registration.email = form[:email]
    end
end
# The ORM representation (using Sequel as my ORM library)
class Registration < Sequel::Model
  set_schema do
    primary_key :id
    varchar :name
    varchar :email
  end
end

Maybe this is something that other folk have already thought of, and I am just catching up, but the proliferation of web MVC style frameworks which mandate persistence layers (eg Rails) makes be think that this may need to be revisited.

Coding Tip #27: Turning Bools Into Enums

| Comments

On my recent project, I have noticed a resurgence in a pattern that I have seen many times previously: where a field which is represented as a boolean needs to evolve to represent more than just two values (true and false). The number of times that I have encounted this makes me believe that you should always start with enum, regardless if the values are True and False, just to make your life easier down the line.

As much as refactoring tools like resharper help you out, when it comes to refactoring a bool into an enum, it’s a pain in the arm. One of these pain points being that quite often, you see:

if (fieldRepresentedByBool) {}

which makes it quite annoying to turn it into:

if (fieldNowRepresentedByEnum.Equals(Enum.True))

Another pain point is refactoring your database is not much fun, especially if you have to ensure that you also migrate data.

The other benefit that you get from enums when compared to booleans is that your method signatures are more expressive. Consider these two signatures (yes, I know completely contrived, but I couldn’t think of a better example), and tell me which one you prefer.

render(foo, true) // where true represents isVisible render(foo, Display.Visible)

So, next time you start to type bool think about using an enum instead.

As a User I Want to Log In

| Comments

The classic log-in story is often the story that new-to-agile-ist assume you need to develop first. In fact, it is often the last story that should be developed.

The problem is that they see the order that stories should be developed in should mirror the process flow of the tasks that the customer needs to take; after all, you can’t buy an item without choosing what you want to buy and you can’t buy anything before you login. This might also be due to the stories revolving around the tasks the user needs to undertake instead of the goals they are trying to achieve.

Now,  if I was to build a classic shop-on-line website, the first story that I would start with would be to implement a page which accepts payment information and a Buy Now button in the middle of the page. What is the customer going to buy? The same product that every other customer will buy. Now, this does not seem to be that fantastic for the user - they don’t even have a choice in what they are buying, but this is actually the best place to start because it is not the As a Customer I want to buy a book So that I can learn new stuff story that we are implementing; it is the As a Business Stakeholder I want customers to buy my products So that I can make a living story. By defining our stories based on goals, and ordering the development based on what is more valuable, we can launch our site with only one story complete and still make money.

Now, lets go back to the beloved login story. One thing that I hate is a website which puts up a high barrier-to-entry before I can buy a product. At a real-life store, they don’t make me fill in a form to say who I am before I can buy my Big Mac meal; there is no real-world equivalent to the login functionality. What is the real reason that I as a customer needs to login? Where is the value? What is their goal? The next story in this area that you could play would be As a Customer I want to view my purchse order in an email So that I can keep a record of the payment. This story could just involve a text field where the user enters their email address if they wish to receive the email receipt (remember, back in the day, receipts from over-the-phone sales would be sent in the post). Again, we can go live with this and we are still not requiring the customer to login.

The final goal that summaries the customers experience is that As a customer I would like the computer to do some work and remember their details So next time I make a purchase, I only need to place items in the basket and checkout.  All this requires is the customers email address (a perfect URN by the way - why would you even think about having usernames???) and a password. Importantly, however, the gathering of this information does not need to occur before they purchase their items! It can happen at the end of the transaction, thereby allowing the customer to complete their goal (purchasing their items) without hinderence. 

The customer’s goals are now met, and the business stakeholder’s goals were met in the very first story, it is only the marketers' goal of wanting to capture information about the customers on the site which has not been met. Usually marketting departments ask that the customers complete a 4 page registration form, in order for customers to register (As a marketer I want to know information about our customers So that I can target our features to meet their needs). But, what value or incentive is there for the customer to fill in this information? To appease both our market departments, and our customers, however, we could incentivise the customers by rewarding bonus points which go towards their next purchase for completing their registration form. But also importantly, this does not stop the customer from spending money on your site.

So, next time you go to add a login box on your site, think about what the customers true benefits are.

Making C# IList Useable

| Comments

Around my neck of the woods, I have been having a theoretical debate with my colleague Dan Bodart as to the best method signature when it comes to collections of data.

Dan’s point of view is that in order to be good citizens, our methods should form around interfaces and not rely on the concrete representation, after all if you need the data as a list, you can always create a new one.

My argument is that the IList interface is so rubbish that you would always need to create a list in order to manipulate it, and then that just becomes noise.

Both sides of the argument have valid points, and valid critisisms. After a little searching, we have found the answer: use extension methods for IList to add the fantastic list methods to the interface. In fact, we have gone one step further, and added extention methods to IEnumerable, so that we can have the power for our dictionaries as well. We have taken the opportunity to add a lot more functional methods  such as Head, Tail, Exists,  Find and AsString.

Here is an exerpt from our class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static class EnumerableExtensionMethods
{
    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach (T t in source)
        {
            action(t);
        }
    }

    public static List<t> ConvertAll<s, T>(this IEnumerable<s> source, Converter<s, T> converter)
    {
        return new List<s>(source).ConvertAll(converter);
    }

    public static List<t> FindAll<t>(this IEnumerable<t> source, Predicate<t> predicate)
    {
        return new List<t>(source).FindAll(predicate);
    }
}

How I Perform Like a P0rn Star

| Comments

After a few days of introspection, I have finally decided to post about my reactions to the now infamous “Perform like a p0rn star” presentation and it’s aftermath.

The Presentation Itself

Looking at the presentation online, without having attended the conference, may exclude me from commenting fairly, but I just think “why”; as in, I don’t get it. I think that there is a tenuous link between the pictures and the slide; one which could also be made with other images. I guess I follow Ted Neward’s feelings that the same effect could of been achieved with subtle imagery, and double-entendres. 

The Audience Members

I wonder how many people in the audience thought this was inappropriate at the time. Clearly, Sarah Allen and Sarah Mei were uncomfortable. How many men in that room looked around to see how the 6 girls were reacting to it? I bet what they saw was an expression that read ‘Oh…haha….’ while really the girl’s inside voices were screaming…‘groan no, not another god-damn picture - we get it already, you are a guy…time to move on’*. With the obvious acceptance of the girls, perhaps the rest of the audience felt the images were ok (at least at first…I think I have seen comments from people who say that the first few pictures were good and funny but the joke wore thin). I would like to think that if I was in attendance, I would have the courage to standup and declare the inappropriateness of the presentation. In reality, I know I would not. I know this for several reasons; firstly, I would actually find that too rude.

Secondly, when at conferences or at the workplace, I try not to draw attention to the fact that I am a woman. Why do I do this? Frankly, because I wanted to be seen as a damn good developer first, and I fear what thoughts some people might have, especially some of the men who fit the stereotypical profile of a single, WoW playing, don’t meet real girls unless they are an elf on WOW (who, I have come to learn are usually men playing women) guy (as irrational as it may be).

Thirdly, I know that is how I would react (ie inaction), because it is the same reaction that I give when I am sitting next to a group of developers (yes, all men) who are talking about putting their girlfriends/wives/women into their place, or commenting on the length of another woman’s legs as she walks past, or other behavior which I would associate with groups of friends at a pub. At a pub, or out with friends I am quite happy for this type of discussion to take plus, but com'on guys, let’s make the workplace gender-free, not equal, and leave our hormones at the door.

The comments along the lines of ‘this should not offend you’ or ‘I’m and Rrated person - deal with it’

Quite frankly, I was not surprised. This is the same type of comments that I get whenever I mention the whole women-in-IT thing. It’s also why I try to not to post too many entries on the subject matter (obviously sometimes I feel the need to speak out about the latest injustice)

The comments along the lines of ‘this is bad. How about we all grow up’

Wow. Every time I read a comment like that, it negated any bad feeling I got from the other type of comments. It is great knowing that there are a large number of people out there, people of influence especially, who are on ‘your side’. When people like Martin Fowler speak out about the Smut in Rails, it really makes you feel like you are on the right side. At Thoughtworks, we had an internal discussion on a mailing list about this, and I was just waiting for someone to say ‘hey, its not so bad’, but still I can’t believe that everyone I talk to about this strongly believes that this is inappropriate. So, thankyou for all who believe in this, and especially thankyou for all those people in a position in power who not only believe in it but also speak out about it.

In Summary

Was I offended by the presentation? I don’t know; I wasn’t there, so I don’t feel that I can really comment.

Was I offended by the reactions and the aftermath? Yeah, I was, although I was not surprised.

Would I want to get in my DeLorean and stop Matt from doing the presentation? Hell-to-the-no. I think that we should embrace this storm and let it be a catalyst to changing our minds, our behavior and our industry.

 

  [Update - I corrected a few places where I used the wrong version of woman/women; also fixed grown into groan - Thanks Simon] *[Note - reading back on this, I feel like I have read it somewhere before on someone elses blog/in a comment. Sorry if I have, but this is still a valid point].

What Is REST?

| Comments

There has been quite a lot of discussion on mailing lists that I am on about what it means to be RESTful. It has occurred to me that the reason for many of these discussions is that people only hear tidbits about REST and therefore draw wrong conclusions about it. Here is my understanding:

Representation State Transfer (REST) was introduced in 2000 by Roy Fielding, who is one of the authors of the HTTP specification. It is an architectural style for the web (or distributed hypermedia systems) which dictates how clients will access your application. It puts the method information in the HTTP method and the scoping information in the URI. There are commonly 4 questions that REST allows a client to ask your application:

  1. can you please GET me the REPRESENTATION for THIS_RESOURCE from your application
  2. can you please PUT THESE_VALUES for THIS_RESOURCE into your application
  3. can you please DELETE THIS_RESOURCE from your application
  4. can you please POST THIS_MESSAGE so THIS_RESOURCE can handle it.

The GET request is idempotent and should not change anything on the server; it is a read-only action. Ideally, these requests should be cachable so that your application benefits from the architecture of the web. Your PUT and DELETEs should be idempotent, which means that it doesn’t matter how many times you send an identical request, the result is always the same as if you only sent down a single request (excluding concurrency issues). The idempotent nature is important as this allows you to have stateless servers. GET and PUT are not Yin/Yang messages - just because you PUT a certain message to a resource, does not mean that you will get that same message back on a GET.

You will notice that unlike many other articles, I have not mentioned or related the verbs to CRUD. This is important to note, as it is something which I think confuses people. The REST representation of the resources dictate how the client would like to view the data, not how the server should manipulate or store that data. Like any good contract, it does not ask you to reveal its internal structure, so long as you satisfy the request. (Note: REST works really well with consumer-driven contracts).

Resources A resource can be anything that is of interest to you. For instance, you might have a resource for a Book, for an author, for many books or for the collection of all authors and all books available. Resources are addressed by unique URIs. Ideally, for humans, you want your URIs to be logical and guessable ie a URI for a specific author would be /author/{authors_name} a URI for all authors would be /author a URI for all the books written by a specific author would be /author/{authors_name}/books. Contradictory to this, it is also good to treat URIs opaquely and therefore you can’t assume a hierarchical nature, eg ISBN is a classic opaque non-hierarchical URN. The more we support this, the more interconnected our websites can be; imagin searching for ISBN:0321125215 and getting all the results from Amazon, Waterstones, eBay and Borders. This is the vision of the semantic web.

Representations A representation is nothing more that a view of a resource. Kind of like shining a light on a cone, depending upon where the spotlight is shining, you may get a circle, an ellipse or a triangle. It does not take away from the fact that the object is actually a cone. And just as shining a spotlight on a cone is like the response of a GET request, the message sent by POST needs specify only parts of the object, perhaps the height of the triangle, or the circumference of the circle.

Jim Webber, Ian Robinson and Savas Parastatidis have written a nice article on how to GET a cup of coffee that I recommend reading.

Happy Ada Lovelace Day

| Comments

Recent psychology research into how a role model impacts careers indicates that women need female role models more than men need male role models. This research highlights the need for female role models in the IT industry in order to positively impact the careers of the few women in it, and also attract more women into the field. One problem however, is that the profile of most women in the industry is very low - after all, when you attend a conference, how many speakers are female? 

In order to address this problem, and also to celebrate the work that women are doing in IT, some smart cookie has come up with the idea of  Ada Lovelace Day, which happens to be today, March 24.

 

Ada Lovelace Day is an international day of blogging to draw attention to women excelling in technology. Women's contributions often go unacknowledged, their innovations seldom mentioned, their faces rarely recognised. We want you to tell the world about these unsung heroines. Whatever she does, whether she is a sysadmin or a tech entrepreneur, a programmer or a designer, developing software or hardware, a tech journalist or a tech consultant, we want to celebrate her achievements.
If you want to read the posts that more than 1633 bloggers have pledged to write, you can find them on the Ada Lovlace Day Collection website.

 

In honor of today, I thought I might give a shout-out to a few of the groovy chick developers that I work with at ThoughtWorks, so happy Ada Lovelace Day Julie Yauches, Elly Gandy, Liz Keogh, Navya Reddy, Isabella Degen and Chrysovalanto (Val) Kousettii.