In my post about my new book, I mentioned that I thought my outline was a little thin, and indeed it was. I left out a large topic about which I planned on writing – “Writing SOLID Code”. Add that in, and things seem a bit more fleshed out. The silly thing was that I was working on that chapter when I put together the outline and wrote the blog post. Anyway, the outline has been updated and all is well. Thanks again for the support. If you want to keep up with the book’s progress, help out answering my silly questions, and generally be supportive, you can sign up at the LeanPub site, or you can join the Google Group.
Here’s some food for thought for my post about not using nil – The Null Object Pattern. Yet another reason never to return nil. Instead of doing that, you can return a null object that won’t cause an access violation and yet won’t do anything. You can check if the object is a null object if you need to. Win all around.
So the rumors were true – Embarcadero has bought the main products of TwoDesk Software. Jacob Thurman has stated that while he’s not now an Embarcadero employee, he will be working on the Delphi IDE. I guess it’s none of our business exactly what the relationship will be, but if Jacob is working to improve what the IDE can do with code and to improve developer productivity in the Code Editor, I’m very happy. I know that Jacob has had a lot of things that he wanted to do, but found it difficult as an “outsider”. Now that he’s an “insider”, I hope he can do them. I think we’ll see some fun stuff coming out of this deal. Congratulations to Jacob, who I hope was well remunerated, and to Embarcadero for the wisdom to see and acquire Jacob’s skills.
True words tweeted by me: “There are two things that developers love to do: Make pronouncements, and point out the exceptions to other developers’ pronouncements.” I like to make pronouncements as you’ve probably noted. I’m always trying to learn new things and new ways of doing things, and I don’t want to be held back by the “well, we’ve always done it that way” way of thinking. I believe that the way software is developed is evolving and improving, and that we’ve found new ways of doing things better. I try to learn those things and blog about them. That’s what I’m trying to do here. If you disagree with what I say, I welcome your comments. But I ask you to consider that maybe I’m actually on to something. I’d encourage you to take the same path I have – the path of learning these new things that developers are finding and doing. For instance, I don’t ever intend on writing another Delphi application without utilizing MVVM. But ten years ago, such a thought would have occurred to almost no Delphi developer. I encourage you to study the SOLID principles, to read Clean Code, to find better ways to decouple your code, and to generally seek out new thinking about software development. I’m a firm believer that there is always a better way, and I encourage you to think so as well.
3 Replies to “Flotsam and Jetsam #93”
Did you read what is said in the paragraph “Criticism” on the “Null Object Pattern” article? Your entire claim of never accepting nil leads to a bunch of anti-pattern usage or making code harder to read or debug. Also in my book the Null Object Pattern is a clear LSP violation when used for anything but a PODO.
When talking about software design it often makes sense to take analogies of the real world (I know you like that, you’ve done that many times aswell) although they don’t match completely of course.
For example when I am not wearing a jacket – I don’t wear a jacket, but I am not wearing a null-jacket. When I write some code that makes me put on a jacket I check if I don’t wear a jacket to put one on and not if I wear a null-jacket (oh btw, hello memory management, who created that null-object again? should I free that? or do I have to create interfaces for every podo in my application now?)
The null object pattern gets a little messy with strictly typed languages. If your function returns TFoo, you have to create a descendant “tFooNull = class(tFoo)” which then you have to write unit tests and code to insure that TFooNull doesn’t cause a defect if one of the methods is called totally by accident. One solution around this is to use a nullable type approach, where the class itself contains a null status. You still have to test methods for null results, but the code would be easier to maintain as each method can take appropriate action if it is in a null state.
Using a simple base class that is null doesn’t work either, as it requires you to use the base class as all of your function returns and then have to use is/as or typecasting (ick) to get at the underlying methods. This feels like a lot of work just to avoid the nil.
Sometimes the simplest solution is to just return the nil, and add checks at places where they are expected, and asserts where they are not. Less to manage. Use nullable types for data fields that can have a null state. Use nil for “nothings here at all”. To me its far easier to always assert an object that I just got back from a function, this way I don’t have a different pattern to invoke for “my code” vs “vcl/3rd party code”.
I myself am not afraid of writing more code to ensure that my code is safe and works properly. In other words — one man’s “Messy” is another man’s “Well done”.
Did you read what is said in the paragraph “Criticism” on the “Null Object Pattern” article? Your entire claim of never accepting nil leads to a bunch of anti-pattern usage or making code harder to read or debug. Also in my book the Null Object Pattern is a clear LSP violation when used for anything but a PODO.
When talking about software design it often makes sense to take analogies of the real world (I know you like that, you’ve done that many times aswell) although they don’t match completely of course.
For example when I am not wearing a jacket – I don’t wear a jacket, but I am not wearing a null-jacket. When I write some code that makes me put on a jacket I check if I don’t wear a jacket to put one on and not if I wear a null-jacket (oh btw, hello memory management, who created that null-object again? should I free that? or do I have to create interfaces for every podo in my application now?)
The null object pattern gets a little messy with strictly typed languages. If your function returns TFoo, you have to create a descendant “tFooNull = class(tFoo)” which then you have to write unit tests and code to insure that TFooNull doesn’t cause a defect if one of the methods is called totally by accident. One solution around this is to use a nullable type approach, where the class itself contains a null status. You still have to test methods for null results, but the code would be easier to maintain as each method can take appropriate action if it is in a null state.
Using a simple base class that is null doesn’t work either, as it requires you to use the base class as all of your function returns and then have to use is/as or typecasting (ick) to get at the underlying methods. This feels like a lot of work just to avoid the nil.
Sometimes the simplest solution is to just return the nil, and add checks at places where they are expected, and asserts where they are not. Less to manage. Use nullable types for data fields that can have a null state. Use nil for “nothings here at all”. To me its far easier to always assert an object that I just got back from a function, this way I don’t have a different pattern to invoke for “my code” vs “vcl/3rd party code”.
I myself am not afraid of writing more code to ensure that my code is safe and works properly. In other words — one man’s “Messy” is another man’s “Well done”.