- It’s #Code2014 time again! Time to tweet out what languages you used for the year. Just list your languages and include the hashtag
#code2014, and they’ll do the rest. Of course, you can include Delphi all you want. I won’t mind.
- Looks like Ray Konopka will be replacing Dr. Bob this coming year for Delphi Developer Days. If you haven’t heard Ray speak, he’s excellent. Really excellent. I’ve been to DDD three or four times, and it’s always great. Adding Ray this year will maintain the high standards that it has always had. Looks like Dr. Bob is just taking some time off from traveling, and Ray is stepping in. Sounds great. And as Cary notes in his blog post, you can get a reduced rate if you register early!
- In a recent post, I talked about
IncludeTrailingPathDelimiterand why you should always use it with your path strings. I should have mentioned that there is also a
ExcludeTrailingPathDelimiterthat is part of the RTL, too, which does what it says – takes off the trailing path delimiter if it is there. I’m not sure why you’d want to do that, but hey, there it is.
- Happy New Year, everyone. I hope that 2015 has everything in it that you want and hope for. In case you were wondering, my New Years Resolutions are to finish my new book and 1920×1080.
I think I’ve mentioned that I have a “challenging” codebase that I deal with in my day job. It’s a classic Delphi legacy app, worked on by numerous different people over the years with multiple different styles and techniques. Part of the product includes the use of an Address Engine – a third-party utility that “scrubs” addresses and ensures that they exist and that they are in a Post Office acceptable form.
Recently, we’ve had to change Address Engine providers. It should have been easy – I had created an interface to isolate the engine before the switch. So I got the new engine all plugged in, ready to go, and it all should have worked. But try as I might, I couldn’t get anything but garbage data out of the engine. Argh. It simply wouldn’t return any data. Now mind you, the DLL in question was written in C, and I had a translation of the *.h file that I was pretty confident in. It all should have worked.
But the problem was much simpler than that – the
*.ini file that had an entry for the path to the postal data was missing an ending backslash. That was it. I put the trailing backslash on the entry (why didn’t the installer do that?) and it all worked.
Which brings me to the point of this blog post: Always assume that your paths don’t have that trailing delimiter, and that it is your responsibility to put it there.
In fact, the RTL provides a routine that allows you to do that very thing:
function IncludeTrailingPathDelimiter(const S: string): string; overload;
IncludeTrailingPathDelimeter will place either a backslash or a forward slash on the end of a path, depending on the operating system’s definition of a path delimiter if there isn’t one there. If there is, it will do nothing. You should use it to ensure that every path string you use has a delimiter on the end of it. Your code should thus assume that all paths have that trailing backslash on it. If you have code that looks like this:
MyFilenameWithPath := SomePath + ‘\’ + ‘somefile.txt’;
this should be changed to
MyFilenameWithPath := IncludingTrailingPathDelimiter(SomePath) + ‘somefile.txt’;
The former code can be buggy – what if
SomePath already has a trailing delimiter? You’ll end up with an invalid path. The latter code has no such problem. It is safe both ways – with and without the trailing delimiter. This is especially necessary when your paths come as a result of user input, such as that
*.ini file above.
The moral of the story: Never assume that your path variables have a trailing delimiter, and always wrap them up with
IncludeTrailingPathDelimiter to ensure that they do.
- I mentioned this video before, but it is so good I’m going to mention it again: Parallel Programming Library: Create Responsive Object Pascal Apps. Danny’s blog is in Dutch, but he has an English entry that includes the source code to his session.
- Something I’m surprised by: The number of questions on the Delphi StackOverflow tag that deal with integrating with Excel. Also, tons of Indy questions.
- This is interesting: Jon Aasenden is creating DelphiArmy – a real, no kidding jobsite for Delphi developers. I’ll be interested to see how that goes. It appears to be alive and running, so make an entry if you need to.
- I’ve mentioned free this tool before, but its usefulness is so awesome that I wanted to point it out again. It’s called “Everything”, and it allows you to search for any file by name on your entire system. It’s lightening fast, and I use it probably twenty times a day to find things I’m looking for. It’s one of the first things I install on a new system. Truly outstanding and amazingly useful. Highly recommended.
- While I’m at this “mentioning before” thing, I’ll give a strong endorsement to the Delphi-built Clipmate. Again, I use this thing about 25 times a day. It’s a clipboard cache that remembers what you’ve put on the clipboard. It’s not free – but it’s well worth the price. Saved my butt a thousand times, too, when I overwrite something on the clipboard that I didn’t want to.
- A little while ago, I wrote an article on VSoft’s command line arguments library. Since then, I’ve discovered a couple of other solutions that might be of interest. First is from John Kaster, TCommandParser, which has an EDN article (it’s mentioned in there, don’t worry) and a CodeCentral entry. Primož Gabrijelčič has created one that uses attributes. And this StackOverflow question has a number of other solutions as well.
- Speaking of command line parameters, how about someone create a default Console Application that has command line processing built right into it. You could go “File|New|Console Application” and have a new console application with command-line options. Maybe there could even be a wizard to define the command line parameters that your console application would have. Just and idea – I don’t have the time to do it right now. 🙂
- A while back, Marco posted about the “TurboPack”, a set of open source libraries over which Embarcadero appears to be taking ownership. I was glad to see SynEdit on that list, as I use that in an app I built, and have always found its varying versions confusing. I hope EMBT is able to tighten that up. Anyway, Marco now has a short video on his blog that demonstrates some of these components working. Nothing big, just a quick look. I think this is a good initiative on EMBT’s part, and so it would be good for those of you that agree to show support as well. You can find links to the code on Roman Kassebaum’s blog. I guess we owe Roman a Thank You as I bet he did most of the work.
- Clearly the focus of the last few releases of RAD Studio have been on mobile development. Some folks have complained that the VCL developer has been left behind. It seems that EMBT has been aware of this feeling, and has been emphasizing that it isn’t true – that there have been quite a few developments for VCL developers, including REST client components (which are remarkably easy to use), app tethering, taskbar components, the Parallel Library, and more. They also have a webinar coming up entitled “Modernize Your VCL Applications Today”. Yes, the focus hasn’t been 100% on the VCL as in days gone by, but the VCL hasn’t been ignored by any means. Quite the contrary.
- Book I’m Reading: Object Thinking by David West. The idea here is that even though we are all using OOP languages now, we are really doing procedural programming inside the world of OOP. West discusses how we need to start thinking totally differently about our code – to think about objects. Interesting so far – not your typical coding book.
- The inestimable Malcolm Groves has a nice series going on the new Delphi Parallel Library. Recommended reading.
- I put a tag cloud over there on the left. Now I just have to remember to put tags on all my posts.
- I welcome feedback on the new blog. As I said, my goal is to keep the blog as simple and clean as possible and the content as interesting and useful as possible.
- I guess I should have realized that such a thing would exist, but I just found the Delphi Reddit. Thanks to folks that post my blog entries there.
- Another entry in the “How did I miss this?” department: A guy named Branko Stojakovic has built a blog covering most of the Gang of Four patterns. Maybe I did mentioned this before – I have a dim memory of it – but anyway, worth looking at and learning from either way.
An important step to writing Clean Code is the notion of separating “commands” and “queries” by using the Command Query Separation Principle. The notion was first discussed by Bertrand Meyer in his book Object Oriented Software Construction. This means that the idea is not new. In its basic form, it means we should separate the things that read data from the system and things that write data to the system.
The Command/Query Separation Principle means that there should be a clear separation between the updating of information and status in your program and the way that you read information from the program. Commands and queries should be separately declared (though you’ll find that commands can call queries but not vice-versa.) It can be a complex as ensuring that reading and writing take place in completely separate object, or as simple as ensuring that commands and queries are simply done in different methods of your objects.
Of course, the first question you’ll have is “What do you mean by ‘command’ and ‘query’?” Well, I’ll tell you.
A query is an operation that returns a result without effecting the state of the class or application. In Object Pascal, this is typically a
function. Queries should not mutate the state of a class. They should be idempotent. That means “denoting an element of a set that is unchanged in value when multiplied or otherwise operated on by itself.” (I had to look that up, by the way….)
As a general rule, queries should return a single value, and “asking a question should not change the answer”. They should be referentially transparent; that is, they should be perfectly replaceable with their literal result without changing the meaning of the system.
What this means practically is that your functions shouldn’t change the status of the system you are working on, whether that be a class, a framework, or an application. You should be able to run a query, i.e. a function, a hundred times in a row and get the same answer back each time. The function, because it doesn’t change the status of the system, can be safely called at any time without repercussions.
Now this should be a general rule — there are certainly cases where your query will change the state of the system (a dataset’s
Next call comes to mind). But generally, it’s a good idea to have your queries not change state.
A command is any operation that has an observable side-effect. It is any code that changes something in your class or application. Typically, in Object Pascal, a command will be a
procedure — that is, code that takes actions without returning a value. Commands can call queries (but queries should never call commands, because commands change the status of the system).
Commands should not in general return values. Thus, the use of
var parameters should be discouraged if not down-right banned.
Don’t Mix the Two
All your methods and routines should be easily identifiable as either a command or a query. Commands and queries should be separate entities in your code — with the exception that a command can call a query if need be. The use of
out parameters in a
procedure will confuse this issue, and thus should be discouraged. If you follow this rule, your code should be more “reasonable” — it should be easier to understand and easier to modify.
CQRS also encourages you not to violate what I consider to be a bedrock of sound development technique: Don’t try to make one thing do two things. For instance, here is some code that does exactly that:
procedure ProcessWidgets(aCollectionOfWidgets: TWidgetCollection; var aNumberOfProcessedWidgets: integer);
This method is a clear violation of CQS [NOTE: I orginally had this as CQRS] as it obviously is trying to be a command and altering the state of the system by processing widgets, but also tries to be a query by “returning” through a
var parameter the number of processed widgets. Instead, the system should have a simple command to process widgets and a separate query to return the number of widgets that were processed. The procedure is trying to be two things at once, and all kinds of mischief comes from making one thing do two things.
Following the CQRS principle in the design of your code will help to ensure the proper separation of concerns, resulting in cleaner, easier to read and easier to maintain code.
Jon Postel was a guy that wrote an early specification for the Transmission Control Protocol (TCP), one of the core protocols of the Internet protocol suite. You use it every day to surf the web, send emails, etc. One of the guiding principles that he used when writing it was this:
Be conservative in what you do, be liberal in what you accept from others.
This idea is also call the Robustness Principle, and is sometimes rephrased as “Be conservative in what you send, be liberal in what you accept.” When applied to TCP, it means that the sender of data should be strict in what is sent, ensuring that it is accurate and precise. It also means that the receiver of data should be forgiving and understanding of data to as large a degree as possible. If you send data, be as clear as possible in what you send. If you can accept the data sent, then you should.
Any application programming interface (API) should follow this principle. Thus, the same principle should apply to your code. The public interface of your class should be viewed as an API, and it should be conservative in what it sends, and forgiving in what it receives. When calling another API, your code should send out data in a completely conformant way, following the rules laid down by the receiving API. But it should be willing to receive input in a non-conformant way as long as the input can be understood.
For instance, if passed a string, you might be happy to accept strings with blank spaces on the beginning and end, and use the Trim function to clean things up for the sender. Your classes might provide overloads for input methods, accepting both and integer and a string as input, providing a way for your class to be as forgiving as possible.
But when you call another API, your code should be strict and always send data in the correct, expected form. You should trim your strings before they get sent along to the API you are calling. If the system expects integers, you are going to send integers. You should meet the specification completely.
Another example is the use of nil. First, your code should never pass nil to a method that you are calling. Always provide a valid instance if the API calls for one. Second, your code should accept nil, but “fail fast” if passed nil and raise an exception. You should never let your internals get into the state of nil, and while you should accept nil, you should immediately raise an exception at any attempt to set one of your internal references to nil.
Postel’s Law – a small but important way to write better code.
Interesting linksHere are some interesting links for you! Enjoy your stay :)
- August 2017
- May 2017
- April 2017
- March 2017
- February 2017
- January 2017
- November 2016
- October 2016
- September 2016
- August 2016
- July 2016
- June 2016
- May 2016
- March 2016
- January 2016
- December 2015
- November 2015
- September 2015
- August 2015
- June 2015
- May 2015
- April 2015
- March 2015
- February 2015
- January 2015
- December 2014
- November 2014