Questioning To Find Hidden Domain Objects

November 3, 2010

Let’s say you’re chatting with business, trying to figure out their domain model. Great. They explain…

  1. Users answer phones, accepting calls from customers with computer problems.
  2. The user gathers contact info from the caller.
  3. The user creates a new ticket.

That’s the intake scenario. Now for the update scenario.

  1. A call might come in from the customer, or from somebody else.
  2. The user might also gain information from another source, like a fax, word of mouth, their own knowledge, etc.
  3. In either case, the ticket is brought up for editing, changed, and then saved.

It can be tempting to have a single domain entity for the above story, let’s name it Ticket. It has fields for Contact Name so who know who has the problem, and Call Date so we can track how long it takes to resolve the issue. Certainly we’d also need fields for status, comments, etc., but those aren’t specific to the topic here. The damage is already done. We have committed one of the great domain crimes… we have conflated multiple domain entities into one!

I’d argue, and in my real life case, it’s clearly true, that the contact information fields do not belong anywhere on the Ticket domain item. They’re two different things. There is a Contact entity, and there is a Ticket entity. Now sure, is a Contact almost always related to a Ticket? Yes of course it almost always is, so they are related, but they are not together! You can have somebody call in, forming a Contact, whose problem is resolved immediately and no ticket is ever opened. You can also have a Ticket where the customer calls in ten times, with updated information and details each time, and you need that captured. And finally, you might be updating a Ticket when there is no Contact for that update at all, the information came from some other source than a phone call. In other words, there is more going on in the domain that you get from an initial naive simplistic model.

In real life I didn’t catch this at first. It was actually a year before I really realized just how badly the domain needed this extra Contact entity. I was a little naive in thinking “surely I can’t understand the domain model so soon” and so I didn’t really try. It would have been helpful to have a trick, a rubrik, for knowing when this was going on.

For example, a client might say “we need a field that holds either the number of days spent, or the dollar amount spent”. I stop right there and try to steer them towards two fields, one for the number of days, one for the dollar amount. If only one or the other makes sense, fine, we can add a validation rule to enforce one of them being blank. But my point is that I immediately detect this as a problem. You can’t have two data types in a single field. It just doesn’t work that way. It’s why we make fun of Prince and his silly symbol so much. Names are always text, not symbols, and if you try to break the rule, everybody laughs at you.

I need a rule like that, that points out missing domain entities, that have been erroneously merged into other domain entities.


Fiona Shrek Got Back

October 29, 2010

This cute little TV movie Scared Shrekless is on.

It kind of scares me that I am attracted to Fiona Shrek.

I don’t think they got the memo that female animated cartoon role models are supposed to be size 0 and in desperate need of a cheeseburger.

Ariel shoulda hada butt… oh right, that doesn’t make any sense for a mermaid. You know what I mean!


McChicken For Dinner

October 27, 2010

There’s a spectrum between literally doing other peoples’ jobs for them, and extreme “somebody else’e problem” thinking.

At one end you create a circle of hangers-on and slackers who know they can get away with less, because you’ll always pick up the slack.

On the other end of the spectrum, you walk out of the pizza parlor with a burned pizza, or out of a fast food restaurant with a chicken sandwich after ordering a hamburger, because you couldn’t be bothered to check your order.

Neither end of the spectrum is any good. But you have to know where you want to be within the spectrum in order to get the most bang for your buck. It’s a balancing act. Being the “indispensable” guy sucks, but McChickens are too dry.


So Long and Thanks For All The Inflation!

October 27, 2010

According to this guy on Reddit, $1000 is “not much”. Eh?

Jen and I were catching up on Castle, and the commissioner made a joke about keeping his imaginary millions of dollars “in his mattress”.

If $1000 is not a lot of money, implying that it used to be, and people should sit on their money, implying that it’s safer to do so than gamble or invest it, then my brain asplode.

Don’t put money in your mattress, because no matter how much you put in there, the bed bugs of inflation will eat it!


Fields and Properties Just Don’t Cut It Anymore

November 15, 2006

Nowadays business objects are built as regular old objects, with private fields and public properties exposing those fields. This allows you to do some nice things. For example you can do some validation in the property setter, or maybe lazy-load a child object in a property getter. And as things get fleshed out you will likely write methods that do all the ADO work needed to insert, update, delete, and query the class based on these fields. But what kills me is how, after you’ve done all this work for all the objects in your whole application… there is a tremendous amount of wasted duplication.Just imagine an application whoose domain relies heavily on one piece of information, say an integer value known as a CompanyID. This value shows up in fully half the business objects, and in the databas, half the tables. In other words it’s everywhere. So you end up with a whole mess of objects that all have a line like this…
Private _CompanyID As Nullable(Of Integer)
Oh and we have to expose it to the world, and so all those objects also have these lines too…
Public Property Company As Nullable(Of Integer)
...
End Property

Oh and they all have to be able to store their company id so there’s a line like this for every object…

cmd.Parameters.Add(new DbParameter(“CompanyID”, DBType.Int32, …

And sure we also need to retrieve it so we’ll have to code this every time…

Me.CompanyID = rdr.GetInt32(rdr.GetOrdinal(“CompanyID”))

And so on and so forth. You get my drift. Validation. Display in windows form for editing. Display in a read-only web form. Making a GridView column for it. Etc. For every object that has a Company ID you’ll have to do all the same work over and over again. This sucks!
Read the rest of this entry »


Variable Metadata

November 15, 2006

Back in the olden days, we used to teach variables by saying “they’re like a mailbox, which holds a value”. In any language that allows you to define your own types, you have infinite flexibility in defining what’s in those boxes. But we’ve never really gotten a lot of power over the box itself. Nowadays we can define it’s name, the type of value it holds, from where it can be accessed, and if you’re lucky, whether it’s empty or not. In .Net there are a lot of boxes that can’t even be empty (structures, such as integers and enumerations). This is tricky enough when you’re just coding away, within the environment itself. But when you need to go outside, such as into any modern database, you run into problems. Blog posts and articles about how to negotiate null values are legion.

What I’d like to do is take the idea of null (C#) or nothing (VB.Net) and run with it. Here’s what I envision being possible for any variable, structure or otherwise.

Undefined
I’d like to be able to talk about variables, properties, methods, etc. even if they don’t exist. To be more clear, I’d like to do it without incurring an exception :)
Dim x = 5
Print ( y )
->"Undefined"

NotSet
This would really help when negotiating with databases, and optional parameters to methods. I’d like it if there was a way for the environment to say “yes, that variable exists, but nobody has ever given it any value”. This is similar to Null or Nothing, but not exactly the same. In this case the value is empty, yes, but it’s empty because it’s never been set.
Dim x
Print ( x )
->"NotSet"

One thing this would let us do is tidy up method definitions by taking out the default value of optional parameters and putting that into the body of the method. Instead of this…
Refresh(Optional forceDb As Boolean = True)
We could instead have this…
Refresh(Optional forceDb As Boolean)
If forceDb Or forceDb Is NotSet Then...

Null
Okay now we get to null, or nothing in VB parlance. This is not the same as the null we use nowadays. It means somebody explicitly set the value to null. They made a conscious decision about it. One thing this can let you do is know if the caller to a method meant to use the default value for a parameter (ie. he passed in NotSet) or if he meant to use null as the value.
Dim x = Null
Print ( x )
->"Null"

Invalid
This is something I think would be really interesting. What if screwing up on a data value conversion or setting didn’t throw an exception, but instead just set the value of the variable in question to “invalid”?
Dim x
x = 2 / 0
Print ( x )
->"Invalid"

This opens up a whole new world of error handling. I’m not exactly proposing that we abandon exceptions or anything. I’m just asking if an exception caused by setting a variable to an invalid value is such a major problem for the application, or if it’s really just a concern of the variable itself. In order to be able to act on the outcome of an invalid variable, we’d need to be able to get at the exception that caused the invalid state.
Dim x
x = 2 / 0
Print ( x.WhyInvalid.Message )
->"Arithmetic operation resulted in an overflow."

Value
Finally, the state we all know and love, the variable has a valid value assigned to it. This doesn’t require much of an explanation ro example, does it?

Tests
In VB.Net we have a nice syntax for testing if a variable is set or not “Is Nothing” (and now in 2005, “IsNot Nothing”). But with the above new states that a variable can take on, we need to be able to ask a lot more questions.
Is Defined True for everything except undefined.
Is Set True for everything except undefined and notset.
Is Nothing True only when the variable was explicitely set to nothing.
Is Valid True for everything except undefined, notset, and invalid.
Is Value True only for the state where the variable has a value, false for all other states.


More Private Than Private

November 2, 2006

We need an access modifier that’s more private than private. Let’s say I have a string field called Name.

Private _Name As String
Public Property Name As String
Get
Return _Name
End Get
Set ( value As String )
_Name = value
End Set

So far so good. Now it’s time to populate this field from an ADO DataReader and so I write a bit more code.

_Name = dataReader.GetString("Name")

Now for a little metaphysical discussion. Technically I have not yet coded any actual bugs. However I’ve done something that will, almost assuredly, become a bug later on down the line. So metaphysically haven’t I coded a bug? There’s a zen koan that goes something like “the fish eying the worm has already been hooked”. The bug is introduced when I change the property setter.

Set ( value As String )
_Name = value
If _Name IsNot Nothing Then _Name = _Name.Trim()
End Set

See I’d like to make sure I don’t have spaces before or after any names. So I adjust the property setter and make sure all values are trimmed. Nice! But now if you go back and look at my ADO code, it bypasses the property setter and sets the underlying private field directly. No trimming will take place!

Okay I know what you’re probably saying. You shouldn’t be using ADO from within the business object. You shouldn’t have set the private field directly in the first place. I know, I know. But I do. What I want is to be able to stop myself from doing it. What I want is an access modifier that says “you can’t access this field from anywhere, not even the class itself, except from with it’s property”. It’d look something like this…

Public Property Name As String
SuperPrivate _Name As String
Get
Return _Name
End Get
Set ( value As String )
_Name = value
End If
End Set

I used SuperPrivate there because I don’t know what I’d like to call this new access modifier yet. But notice that the definition of the SuperPrivate field is inside the property definition. Within the setter and getter of that property is the only place that you can access this field. Not from the code in the rest of the class. Now it’s possible to prevent myself from ever making the sort of mistake that leads to private fields getting set with bad data because I set them directly from within the class, instead of using the property setter.


Follow

Get every new post delivered to your Inbox.