A long time ago, I considered the following question: how can I design the signature of a function that returns the largest number from an integer set? At that time, I was stranded because I didn't come up with a satisfactory answer. I think again today and finally realize it! Now, we can see the whole process of thinking here.
The most intuitive function signature design is as follows:
Int Getmaxelement (arraylist elelist );
At first glance, it is very good, and it directly reflects the intention. If elist is null or the number of elements is 0, what does getmaxelement return? First, change the signature to the following format:
Bool Getmaxelement (arraylist elelist, Out Int Result );
I asked a lotProgramStaff, almost all of them are handled in this way. I think it is awkward to design functions like this. I like intuitive and simple solutions. Undoubtedly, I like the first signature form, and it reflects the intention of the function. In the second case, its design is not good enough. Besides being not intuitive enough, what are the more important defects? Today I know the answer.
First, let's look at it. If elelist is null or the number of elements is 0, does getmaxelement know how to handle this problem? Of course, I don't know! Because all related contexts in this function have been lost, who knows the processing method? Yes, it is the caller who calls getmaxelement. Before calling getmaxelement, the caller should check whether elelist meets the conditions. So, where is this condition defined? The current solution is in the getmaxelement Function Description document.
The caller does this:
Arraylist elelist =
If (Elelist = Null ) | (Elelist. Count = 0 ))
{
//Handling error
}
Int Max = Getmaxelement (elelist );
Since the caller knows how to handle the error context where elist is null and the number is 0, it is easy to solve this problem. If the second signature is used, what are the defects? In the case of the second signature, the caller usually does this:
Arraylist elelist =
Int Max = 0 ;
Bool Succeed = Getmaxelement (elelist, Out Max );
If ( ! Succeed)
{
//Alas, I don't know what to do.
}
To if (! The caller does not know whether the error returned by getmaxelement is caused by the null elist and the number of errors. The root cause of the error is lost, therefore, the caller can't help but sigh!
Here, I have summarized a design principle:
Do not let the error spread. Solve the error in its infancy! The more an error is transmitted to the end, the more context information is lost for processing it!
Add comments to the getmaxelement method, which is like this:
// Before calling this function, make sure that elelist is not null and the number of elements is greater than 0.
Int Getmaxelement (arraylist elelist );
This actually limits a precondition. For more information about the preconditions and the preconditions, see "contractual design "! At this point, I want to implement a contract facility dbc.net on the. NET platform, which will automatically detect preconditions and post conditions at runtime. It is likely to look like the following:
[Precondition (elelist ! = Null )]
[Precondition (elelist. Count > 0 )]
Int Getmaxelement (arraylist elelist );
If you have any suggestions for implementing dbc.net, please feel free to discuss them with me. I have applied for the dbc.net column http://www.cnblogs.com/dbcnetin my blog. welcome to join us!