Why we’re all doing objects wrong

The object’s interface consists of a set of commands, each command performing a specific action. An object asks another object to perform an action by sending it a message.

From http://www.inf.ufsc.br/poo/smalltalk/ibm/tutorial/oop.html (emphasis mine)

It struck me recently that the vast majority of ‘objects’ that I’ve coded haven’t actually been objects, in the purest sense of the word. Take this as an example:

public class Survey
{
  public int Id { get; set; }
  public DateTime SurveyDate { get; set; }
  public ICollection<Surveyor> Surveyors { get; private set; }
  // etc
}

In a typical Enterprise Application, we code dozens – hundreds – of “classes” like these. For the most part, they replicate what’s in the database, and carry nary a whiff of that pagan idol, “Business Logic”. What logic they do have is generally in the order of:

public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName {
  get { return string.Concat(this.FirstName, " ", this.LastName); }
}

It’s not bad code, it’s not useless, but it’s not really an object – it’s a record.

The typical business application starts life as a database, or at least deals primarily with the input and output of data from a store. The data itself does very little other than trickle from the database into some sort of application code and into a UI. What logic it does have is usually UI logic (see the above example) – syntactic sugar to avoid repetition in the UI layer.

Occasionally, an object will encode validation rules, but these tend to be reflections of the database rules, and very rarely do they go beyond “field is required”.

The objects that we’re coding are the messages that the definition above speaks of – we code them, we build data access layers to load and save them, and we build UIs to display them.

So where does the real business logic lie – where are the real objects? In reality, I suspect that the vast majority is pushed into the database, into tangled stored procedures, patched and hacked and maybe, if you’re lucky, kept in source control. More logic tends to live in MVC controllers, the code-behind of WebForms pages, embedded deep in classic ASP or PHP pages, VB or WinForms, and on and on. Be honest: you’ve seen or written code like this before:

public ActionResult Create(Survey model)
{
  if (repository.Surveys.Any(s => s.Code == model.Code))
    ModelState.AddModelError("Code", "Code already exists");

  if (!ModelState.IsValid)
    return View(model);

  var property = repository.GetProperty(survey.PropertyId);
  property.DateOfLastSurvey = model.SurveyDate;
  property.Surveys.Add(model);

  repository.SaveChanges();

  emailer.SendEmail(property.ManagerEmail, "New survey entered", "blah blah blah");
  
  auditLog.RecordCreated(model);
  auditLog.RecordUpdated(property);

  return RedirectToAction("Created", model);
}

OK, so it’s MVC, but it could just as easily be a CreateSurveyButton_Click event handler, or create_survey.php or whatever – it’s not bad code, it’s not even particularly verbose, but it’s making up the business logic as it goes, making the assumption that the developer knows what the logic is, and that it’s so obvious that it doesn’t need to be encapsulated into an object.

(As an aside, this is why I have a problem with people who have a problem with “xxxManager” objects – you know what, SurveyManager is a perfectly good name for an object if you can’t think of a better one!)

Objects are Services

Look at the MVC example above – in reality, the object here is the MVC controller itself. Similarly, I’ve seen SOAP or REST services which could qualify. Have a read of Bob Martin’s post here: http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html

Martin makes the excellent point that an object is nothing if not a service – whether it’s implemented as a SOAP endpoint, a queue, a PHP script, or just an object in a DLL. You can write a beautiful service-oriented-architecture in a single-project console application, if you structure it correctly, and if you take the time to really think about what your objects are.

Your objects are not your data.

Your data are the messages passed to and from your objects.

Advertisements