The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Nullable types

Hi all,
I'm trying to design the domain model of an application. Since I'm using VS.NET 2005 which support nullable types I'm wondering if the properties of my object should be of nullable types or not. The question can be also expressed as:
Should I abstract the null values in the domain model so I don't deal directly with them from higher level code or should I expose them and the higher level code deals with them? Any help is appreciated.

Thank you
Albert Tollkuçi Send private email
Monday, October 16, 2006
 
 
In what cases would you actually need null values in your primitive variables?

Usually, in my experience, any DB column where you might be tempted to allow nulls is really a case where you ought to have a new table. Allowing nulls all over the place means you're inviting invalid data into your database.

I was disappointed to see nullable types added to the .NET environment. I think nullable types encourage slopyy data design.
BenjiSmith Send private email
Monday, October 16, 2006
 
 
Thanx for the reply, but let take this case. I have some entities which are valid for a certain amount of time between 2 dates. Now if an entity is valid from today it does not have a "valid to" date, so that's a null value. Should the ActiveTo property be of DateTime type, Nullable<DateTime> or should I have a new table for this (I think the DBA would not agree with the third option).
Albert Tollkuçi Send private email
Monday, October 16, 2006
 
 
+1 Benji:

"Usually, in my experience, any DB column where you might be tempted to allow nulls is really a case where you ought to have a new table"

Nulls are bad for you.
D in PHX Send private email
Monday, October 16, 2006
 
 
Nulls may be "bad"...but it some cases they are the most elegant solution...like the above case.
Now that I was thinking it again...it seems reasonable to have fields of nullable types and properties of standart types. This way you can deal with nulk values withing the domain model and the higher level code doesn't have to deal with them. Any idea????
Albert Tollkuçi Send private email
Monday, October 16, 2006
 
 
I agree that using null to have special meaning in the doamin model should be avoided.  In your example of active_to date, I'd rather use DateTime.MaxValue.  Then I can check active_from <= now <= active_to to see if it's currently active without fooling around with null.  This is an example of the NullObject pattern.
Mike S Send private email
Monday, October 16, 2006
 
 
As I explained before I used nullable types for the fields and standard types for the properties. Then depening on the semantics the property returns a appropriate value if the field has a null value...seems to work
Albert Tollkuçi Send private email
Monday, October 16, 2006
 
 
I think Date type is a special case. Long story short, if I were you, I would treat certain date values as 'empty' or 'null', such as MinValue/MaxValue and do a conversion by a shared/static function between data access and business layers.
hobit Send private email
Monday, October 16, 2006
 
 
You really think magic numbers are preferable to nulls?
Kyralessa Send private email
Monday, October 16, 2006
 
 
If it's a 'magic value' like DateTime.MaxValue, for a 'valid from now until maybe forever', then yes, I think that makes a lot of sense.

If it's a 'magic value' like zero, or 1, or -1, well that's harder to justify.

"Null" to me means "not defined" -- not yes, not no, just 'not defined'.  If you have a duration record that has a start time, it MUST have some kind of end time.  'MaxValue' is a nice stand in for 'forever'.

Better than a 'null' time, but that's just my take on it.  'null' could also work there.
AllanL5
Monday, October 16, 2006
 
 
I absolutely agree with Allan. The correct answer for this particular design is to use DateTime.MaxValue for entries from now till the end of time, and DateTime.MinValue for entries from the beginning of time till now.

If you use nulls as a magic value meaning "either the start or the end of time, depending on the column", then I'd like to see you write an elegant query that tests whether a given date value falls into the record's range.
BenjiSmith Send private email
Monday, October 16, 2006
 
 
Well, DateTime.MinValue and DateTime.MaxValue are outside the valid date range in SQL Server, so I have to use some other dates, which will be basically magic dates.
I agree that null values should be avoided, but there are cases that u need them...
Albert Tollkuci
Tuesday, October 17, 2006
 
 
In my opinion nulls are not bad at all in terms of their existence within the representation of a data model they are just sometimes a pain in the ass to error handle against...

The quickest way to crash an app is to miss error handling nulls...
Brice Richard Send private email
Tuesday, October 17, 2006
 
 
<<If you use nulls as a magic value meaning "either the start or the end of time, depending on the column", then I'd like to see you write an elegant query that tests whether a given date value falls into the record's range.>>

Someone has no clue on how to think out of the box.

In the scenario you described, there is an easy solution. If you have a null as the "magic value" as you suggested, you simply create a CALCULATED field that defines the null within a new search string. For example, you create another field that substitutes all null values in field x for a value in field y such as "Pending" or any other appropriate term. Using this protocol you can then even expand upon your business logic to add even more complexity to this field value based on other data elements within your table.

In your query you would query the database for all known records having the "Pending" attribute for which you can then process.

How hard is that?
Brice Richard Send private email
Tuesday, October 17, 2006
 
 
Why do you invent special values which should replace null? Null is invented so that we have common point for all situations where value is not defined.

How do you handle referential integrity in cases where related record is not defined on insert?
E.g. - task that have to be assigned to employee. Task is created, boss did not pick person that is going to do it. Task can be assigned to only one employee.
You can extract task and employee relation in separate table, but then you created another problem - you must prevent task to be assigned to more than one employee. Avoiding null shifted problem to other area, but there is still complication.

There are "workarounds" for avoiding nulls, but why if it leads to problem that would not exist if you use null.
moronica
Tuesday, October 17, 2006
 
 
The initial question was should I use Nullable types in the Domain Model?
Albert Tollkuci
Tuesday, October 17, 2006
 
 
I don't personally find nullable types to be that valuable. The most common scenario for allowing null in a database column is for DateTime fields. But a DateTime in C# can be represented with a standard null value instead of going to a nullable type. Only value types like integers, longs, booleans, and such that don't already have the concept of a null reference end up benefiting from nullable types.

So if you have a string or a datetime column in the db, just use a standard null reference value to indicate this if needed. Why use a nullable type for something that already supports a null reference value?
anon
Tuesday, October 17, 2006
 
 
DateTime is a struct not a class so it does not support null values.
Albert Tollkuci
Tuesday, October 17, 2006
 
 
"How do you handle referential integrity in cases where related record is not defined on insert?
E.g. - task that have to be assigned to employee. Task is created, boss did not pick person that is going to do it. Task can be assigned to only one employee.
You can extract task and employee relation in separate table, but then you created another problem - you must prevent task to be assigned to more than one employee. Avoiding null shifted problem to other area, but there is still complication.

There are "workarounds" for avoiding nulls, but why if it leads to problem that would not exist if you use null."

That's the issue though. Or should I say the misunderstanding.

Pulling it out to separate tables is not a 'complication'. It's the way relational theory works.

NULLs are terrible. Are you aware of the amount of 'null handling' settings there are in SQL server alone?

Treating NULLs like another allowable value is a mistake.

On the other side of the coin, the magic number suggestion isn't much better.

Now everyone has to remember that they have to filter out MinDate or MaxDate everytime they use the column.

Counts. Sums. Ranges. Yuck.

It's one thing to have to kludge a Null value or magic number if you can't change the model, but planning to do it is like planning to be hit by a bus IMO.
D in PHX Send private email
Tuesday, October 17, 2006
 
 
@ OP:
"The initial question was should I use Nullable types in the Domain Model?"

Yeah, I guess this discussion got a little hijacked.

I would say no. If you have an instance of an object I would assume that you have all the info needed to describe it.

By my opinion, NULLs are the complete opposite of description.
D in PHX Send private email
Tuesday, October 17, 2006
 
 
I'd say use nullables where nullables make sense.  I prefer nulls to "special" values that I have to reinterpret.  Also, if you have a set of total functions (functions defined over all possible inputs), how do you signify that a certain input has not been defined?

Your best bet is to see if you can ensure that the object is in a meaningful state after construction and that the object stays that way throughout its lifetime.  Then, you don't need to worry about nulls.  If you can't do that, then a null is my preferred way to signify that "this value hasn't been provided"
Frank
Tuesday, October 17, 2006
 
 
an excellent example was brought up: the task/employee.  This is the perfect situation to use null.  Not every task is always assigned to an employee when it is created, at least in the real world.
Tom C
Tuesday, October 17, 2006
 
 
I disagree that null is appropriate for the task/employee design.

Instead of putting nulls into the tasks table, add a new joiner table linking tasks with employees (which also eliminates the question of whether a task owns an employee or whether an employee owns a task).

If you want to ensure that a task can never be assigned to more than one different employee, put a UNIQUE constraint on the task_id field of the joiner table. If you want to make sure that a single employee is never assigned more than one task, put a UNIQUE constraint on the employee_id field.

Then, someday, when your tasks become so complicated that they require multiple employees, you can simply lift the uniqueness constraint on the 'task_id' column, and continue to use the same table for a one-to-many relationship. And, if your employees become so overworked that they need to each handle multiple tasks, you can lift the uniqueness constraint on the 'employee_id' column.

Why is using nulls preferable to using a joiner table in cases like this, where you're representing a relationship between two entities?
BenjiSmith Send private email
Tuesday, October 17, 2006
 
 
I tend to prefer the "joiner table" approach as well, but it can degrade performance some relative to the null foreign key approach, especially if you have to walk along chains of relationships.
snoozy Send private email
Tuesday, October 17, 2006
 
 
well for one thing, you aren't always using a database.  Let's see here is the software that I currently use, those that use a database of some sort are marked with an *:

work:
Powerpoint
Falcon View*
Access*
Analyst's Notebook*

offtime:
CodeBlocks (IDE)
Visual Studio 2003 (compiler only)
Civilization 4

Nullable types can be used for more that just database stuff.  For one thing C, C++, and Java all have nullable pointers.
Tom C
Friday, October 20, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz