Keeping track of an objects status

by Noceo   Last Updated March 13, 2018 08:05 AM - source

One thing I always struggle with, when designing software, is to find a good way to keep track of an objects status.

For example, lets say I wanted to keep track of a car being build. It could can a status of "Paint job completed". But from a different perspective, this status could also be considered "Ready for assembly". Or from a sales perspective, it would be "In production".

So now, my code object for the car, would contain three properties:

public string StatusFromPaintShopPerspective { get; set; }
public string StatusFromAssemblyPerspective { get; set; }
public string StatusFromSalesPerspecitve { get; set; }

Now obviously I could just have the status as an ID (and in this case I probably would), but what if something goes wrong and the status changes to "Requires manual attention" (or the ID for that status). In that case, the status wouldn't tell me how far it was in the process, only that it requires manual attention.

So where am I going with this? I always struggle to design good systems for tracking a status. And I find it difficult to believe, that I am the only one who struggles with this. But I cannot find any good articles or literature on the topic.

Does anyone have any suggestions for learning material, in respect to process tracking? Or if you simply have some good design ideas of your own, I am also very interested in those.

Answers 2

The trouble here is that you have three properties to represent just one value - you shouldn't be able to independently set the "sales status" and the "paint shop status", because the first is dependent on the second. Instead, have one single source of truth for the status, and the different views onto that status: for example, "sales status" should just return "still in production" or similar if the underlying status is in any of the states which indicate the paint shop work is incomplete.

I suspect you will find you need to consider the status as a tree rather than a linear process, but that's down to the complexity of the system you're modelling.

As for "needs manual attention", that probably becomes a boolean flag and gets reflected into the high-level status reporting.

Philip Kendall
Philip Kendall
March 13, 2018 07:35 AM

I would normally place responsibilities for complex creation processes and their tracking states into a separate object like a CarBuilder. But for the sake of demonstration, lets assume those properties are part of a Car.

lets say I wanted to keep track of a car being build. It could can a status of "Paint job completed".

A basic property of a car could be its Color (with a special value None for unpainted cars). So a status like "Paint job completed" is already a derived property, and a boolean PaintJobCompleted status may look like this:

          public bool PaintJobCompleted
              get{return Color!=Color.None;}

(As I wrote, this property is IMHO better placed in a CarBuilder, since a car object should not know there is a "paint job" involved to make it colored, but lets ignore this).

But from a different perspective, this status could also be considered "Ready for assembly"

Lets assume "ready for assembly" involves the car being painted and the wheels being available, and WheelsAvailable being another boolean property. The dependency between those states then leads to a property like this one:

 public bool ReadyForAssembly
    get{return PaintJobCompleted && WheelsAvailable;}

Or from a sales perspective, it would be "In production".

Lets say a car has an array of wheels, and when that array is not null, the wheels are assembled.

 Wheel[] wheelsArray;
 public bool WheelsInPlace
    get{return wheelsArray!=null}

"In Production" may be true as long as the car is not painted and the wheels are not in place:

 public bool InProduction
    get{return ! (PaintJobJobCompleted && WheelsInPlace);}

So I hope you get the idea:

  • make a clear distinction between basic properties (or attributes of the object, which are mostly independent from the process), and derived properties

  • assign only storage for those basic properties, and encode the business rules for the derived properties into their implementation

Of course, there might be derived properties with complex business rules where storing them internally (as a cache) becomes necessary for performance reasons. But I would recommend to avoid this as long as you don't measure a noteable performance impact.

Doc Brown
Doc Brown
March 13, 2018 09:23 AM

Related Questions

Building entities first

Updated November 23, 2017 17:05 PM

Modelling objects relationship

Updated March 19, 2017 07:05 AM