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.

wide interface

I am working on C# database project and we have no leading architect. On most design decisions we must reach consensus after lengthy discussions. Most senior developer among us is Java expert and he decided, that all public properties of all domain model objects will be nullable (Nullable<int> instead of just int). He argues, that parameter-less constructor will create empty object and later all properties must be set by setters, as a result also immutable objects (eg for reporting) will have setters.
I strongly disagree with this concept and want to limit the interface of objects for instance by not providing setters for immutable properties and by allowing nullable properties only it makes sence.
Can anybody point me to some internet resource, where I could find arguments for my oppinion?

FrankB
Frantisek Bachan Send private email
Wednesday, February 14, 2007
 
 
http://www.egjug.org/book/print/7 scroll down to item 51, "Prefer compile-time errors to run-time errors." It's cheaper to catch errors at the compile phase (because the compiler reports syntax errors) than while the program is running.

If you had a setter for an immutable property but you tried to call it anyway, you won't be alerted to the problem until the program is running. But if you didn't have a setter to start with and you tried to call what you thought might be the setter, you'd get a compile error.

The same goes for using nullable properties vs. parametered constructors. With a parametered constructor, you can prevent errors where the user of your class forgot to call a required setter. But there are also times when using only setters is useful, such as when some parameters are optional. I agree with you, use them when they make sense.
dev1
Wednesday, February 14, 2007
 
 
Surely if a property has a setter then it's not immutable?
John Topley Send private email
Wednesday, February 14, 2007
 
 
>>allowing nullable properties only it makes sence.<< (sic)

Boy, this is a toughee.  I tend to agree with you, but the problem I've encountered is that "when it makes sense" is not constant.  When a property could be null seems to change through the life of an application.  What you think is nullable (or not nullable) today could be different next month, thus requiring more refactoring.

I'll be following this thread with interest.
OneMist8k
Wednesday, February 14, 2007
 
 
"When a property could be null seems to change through the life of an application."

True, but there are dozens of things that change througout the life of an application. There is no way to anticipate everything. For many of the things we can anticipate, the only reasonable solution is to implement in the least restrictive way and that often breaks today's requirements.

I say that the right thing to do is to build for today using techniques and strategies that have proven to ease maintenance over the long term. Things like separation of UI from business rules, etc. Nullable types? Well, maybe, but today's requirement might require adding code to actually prohibit nullability, so now you've made a little bit of work to accomodate the undefined future, then done more work to prevent that undefined future from being realized anyway.

I certainly don't qualify as an authoritive source you can quote, but surely there's volumes written on how pointless it is to do 'make work' or to predict the future. This sounds like a little bit of both.
Ron Porter Send private email
Wednesday, February 14, 2007
 
 
The right thing to do in this case is probably to create a factory and instantiate the objects via that.  That factory can then call the empty constructor and all the necessary setters.  Depending on where you put the factory method, you can make the setters for the immutable fields private, protected, or package protected as you like, preventing anyone from calling them again.

It sounds like your senior dev would like a factory because it's all patternsy and it creates more code. ;>
Art Send private email
Wednesday, February 14, 2007
 
 
As soon as I read "All X of Y shall be Z", the alarm bells go off!

Design each class to meet the needs that you have right now. When you need something else later on, add or change as necessary. While this might occasionally require a bit of refactoring, it's much quicker and cleaner than trying to think up a bunch of universal rules and then figuring out how to twist your requirements to fit into your pre-conceived framework.

end rant.
Mike S Send private email
Wednesday, February 14, 2007
 
 
Thanks dev1 for pointing me to the good article.
I think, in this case several other rules are applicable:
10. An indirection should have a meaning (our guys created over-engineered solution with many extra levels of indirection and now the framwork asks its price: forcing us to allow acces to fields which can never change form business point of view)
17. Less is more.
28. Objects should not simply hold some data.
53. Keep things as “private as possible.”

Anyway, I strictly disagree with anyone saying "things can change in future, lets make interface wider now". Part of design decisions is also to define which features will NOT be implemented and good system analyst puts also these things in functional spec. My rule of thumb is "functionality not required shell not be implemented".

FrankB
Frantisek Bachan Send private email
Wednesday, February 14, 2007
 
 
"Today's requirement might require adding code to actually prohibit nullability, so now you've made a little bit of work to accomodate the undefined future, then done more work to prevent that undefined future from being realized anyway."

Finally, someone gets it. Thank you for making my day! Can you give my boss a call and explain this philosophy to him?
Greg Send private email
Wednesday, February 14, 2007
 
 
I've seen this idiom where immutable classes have setters for initialization rather than a do-all initializer. That design allows you to start with a set of defaults, then set only the parameters you really need to be different. It's nice to be able to do that.
Scott
Thursday, February 15, 2007
 
 
I guess in C++ setters are not const member functions, so the compiler will flag set calls if you actually create a const instance of the class. Perhaps Java is not so flexible.
Scott
Thursday, February 15, 2007
 
 
Sorry, C#.
Scott
Thursday, February 15, 2007
 
 
"I've seen this idiom where immutable classes have setters for initialization rather than a do-all initializer. That design allows you to start with a set of defaults, then set only the parameters you really need to be different."

I'm sorry, but I don't see how such a class can be called immutable.
John Topley Send private email
Friday, February 16, 2007
 
 
Two points:
1. Getters and setters are evil.  At least Allen Holub says so, and I believe him.
2. I also don't like the idea of constructors constructing invalid objects.  If an invalid object cannot be constructed you don't have to put as much error handling in methods.  Same idea as in RAII.
Jeff Zanooda Send private email
Friday, February 16, 2007
 
 
"I also don't like the idea of constructors constructing invalid objects."

Does this include the case where an object is created and then initialized by a factory object so that the factory object is the only one ever able to see the object in a partially initialized, invalid state?
Franklin Send private email
Friday, February 16, 2007
 
 
It's probably ok.  Generally speaking, the design that won't let you express certain common kinds of errors is often better.  For example, any aircraft type that has retractable landing gear will sooner or later participate in a gear-up landing.  One way to prevent it from happening is to have fixed landing gear :)
Jeff Zanooda Send private email
Friday, February 16, 2007
 
 
"I also don't like the idea of constructors constructing invalid objects."
Absolutely, no compromise in this point.

"Does this include the case where an object is created and then initialized by a factory object so that the factory object is the only one ever able to see the object in a partially initialized, invalid state?"

I think you should avoid this construct, for me this is a typical case of a bad programing practice. You can always refactor your code and pass all data necessary to fully initialize the object into constructor as parameters.
Frantisek Bachan Send private email
Monday, February 19, 2007
 
 

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

Other recent topics Other recent topics
 
Powered by FogBugz