Plain Old Dart Objects

As a C# developer, I use auto-implemented properties all the time, typically to create POCOs:

 

class Customer
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string City { get; set; }
  public DateTime Created { get; set; }
}

The compiler will generate an invisible (well, sort of) private member field for each property, which can only be accessed through the getters and setters. Why is it a good practice not just make the member field public, by the way? Because we might wanna add some validation logic later, and changing it from a member field to a property will require recompilation on the caller side. Which is in particular inconvenient if the binaries have been shipped. Also, subclasses can override properties and add logic to them - in C#, it's not possible to override a member field with a property.

Now, let's write the POCO in Dart (which I guess makes it a PODO):

 

class Customer
{
  String FirstName;
  String LastName;
  String City;
  DateTime Created;
}

As simple as it gets. One thing you'll notice is that there is no public access modifier. That's because in Dart, there are no access modifiers: if a member attribute starts with an underscore, it's private (to its library). Otherwise, it's public. I think that's great! Typically, programmers use the underscore notation (or a similar prefix such as m_) by convention anyways. So, having an access modified and the prefix is kind of redundant.

Also, unlike in the C# version, nothing appears to tell the compiler to wrap those attributes in auto-generated getters and setters. That's because the Dart compiler always implicitly generates them (except for setters on final attributes)! Well, as an optimization, it might not really do that although the Dart documentation does make that claim. But the important part is that you can pretend that it does, and if you should choose to make the getters/setters explicit later (or override them in a subclass), you have a guarantee that nothing will break. For instance, here's how we might add some validation logic later and/or in a subclass:

 

String _firstName;
String get FirstName 
{
  return _firstName;
}

set FirstName(String value)
{
  if (value == "Dirk") throw new Exception("No Dirks allowed here.");
  _firstName = value; 
}

There's one more thing: frequently, you're going to instantiate all the member fields of a POxO at instantiation. Here's how Dart allows you to define a constructor for just that:

 

Customer(this.FirstName, this.LastName, this.City, this.Created);

Hmm... syntactic sugar, sweet!



Written on September 22, 2013.