Construction and validation of Java and Ceylon objects

When transforming java code into Ceylon code, I sometimes encounter situations where some Java class constructors confuse validation with initialization. Let's use a simple but artificial code example to illustrate what I want to say.

Some bad code

Consider the following Java classes. (man, don't write such code at home)

Hey, I've warned before that it's man-made. However, it is not uncommon to find something like this in real java code.

The problem here is that even if the validation of the input parameter (in the hidden parsedate () method) fails, we will get an instance of period. But the period we obtained is not a "valid" state. Strictly speaking, what do I mean?

Well, if an object can't meaningfully respond to a public operation, I'll say it's in an invalid state. In this example, GetStartDate () and getenddate () will throw an IllegalStateException, which I don't think is "meaningful".

On the other hand, in this example, we have a type safety failure when designing period. Unchecked exceptions represent a "vulnerability" in the type system. Therefore, a better type safe design for period would be to not use unchecked exceptions -- in this case, it means not throwing IllegalStateException exceptions.

(in fact, in real code, I'm more likely to encounter a GetStartDate () method that doesn't check for nulls, which will cause a NullPointerException exception after this line of code, which is even worse.)

We can easily convert the above period class to Ceylon type class:

Of course, this code will encounter the same problems as the original java code. Two assert symbols shouted at us that there was a problem in the type safety of the code.

Make java code better

How can we improve this code in Java? Well, here's an example. The checked exception criticized by Java will be a very reasonable solution! We can slightly modify the period to throw a checked exception from its constructor:

Now, using this solution, we won't get a period in an invalid state. The code instantiating the period will be handled by the compiler when the input is invalid, and it will catch a dateformatexception exception.

This is a good, perfect and correct use of checked exceptions. Unfortunately, I rarely see java code using checked exceptions like this.

Make Ceylon code better

So what about Ceylon? Ceylon has no checked exceptions, so we need to find a different solution. Typically, Ceylon calls a function to return a union type when Java throws a checked exception when calling a function. Because the initialization of a class does not return any type except the class itself, we need to extract some mixed initialization / verification logic to make it a factory function.

According to the type system, the caller is obliged to handle dateformaterrror:

Or, if we don't care about the actual problem of a given date format (this is possible, assuming that the initialization code we work on loses that information), we can use null instead of dateformaterror:

At the very least, the method of using factory functions is excellent because it generally has a better isolation between validation logic and object initialization. This is particularly useful in Ceylon, where the compiler adds some very strict restrictions to the object initialization logic to ensure that all fields of the object are assigned only once.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>