First check or try to catch?

Let's say I have a function that looks like this:

public void saveBooking(/* some inputs */) { //save into database } 

Before saving to the database, I have to perform various checks. What I can do in my main program is as follows:

 //do all the validations and do any necessary handling. Then... saveBooking(/*inputs*/); 

At the same time, I am sure that all data must pass all the checks necessary to save it in the database. However, this means that the saveBooking() function is saveBooking() dependent on validation methods. Every time I want to call saveBooking() , I have to make sure that I remember calling checks.

Alternatively, I can put all the checks inside the function itself so that all I had to do is call the method and everything will take care. However, in order to handle all errors on my own, I need to make an exception function and catch it in the main program. It should look something like this:

 public void saveBooking(/* some inputs */) /* throws various exceptions */ { //various validations //save into database } //...and in the main program... try{ saveBooking(/*inputs*/); } catch(MyException1 e1){ //do something } catch(MyException2 e2){ //do something } 

It also means that I have to create a few exceptions myself. It’s good that I don’t have to worry about which checks I should set for myself.

With these, I'm not sure which one is the best code design. I personally prefer the first method, which is more readable, but it depends too much on each other, and it gets worse when I need to use it in many places. Please advice!

+8
java
source share
5 answers

Definitely the first option over the second. I think the second is abuse of exceptions. Exceptions are for exceptional circumstances, and refusal of verification is not β€œexceptional”.

Every time I want to call saveBooking() , I have to make sure that I remember calling checks.

Put the validation logic in a separate method and saveBooking() call the validation method before it does anything else.

 public List<ValidationError> validateBooking(/* args */) { // as @Jared Farrish suggests, return a list of validation errors } public boolean saveBooking(/* args */) { List<ValidationError> errors = validateBooking(/* args */); if (errors.size() != 0) return false; // validation failed // save to the database return true; } 
+7
source share

Validation should usually be performed within the function itself so that it is not possible to try to save data without prior validation. Without these checks inside the function, you can find a client trying to save without checking, and this is rarely good.

But you are not limited to using exceptions for this, you can simply return an error code that will be checked by the caller. While it usually doesn't matter to me whether errors are executed using exceptions or return codes, there are some that may see this abuse of exceptions.

The verification code is probably still left as a separate function, since your own code may want to call it without saving. Something like (pseudo code):

 def validateStuff(): if stuff is not valid: return WTF return OK def saveBookings(): rc = validateStuff() if rc != OK: return rc; save the information return OK 

You will still have exceptions thrown by your call to saveBookings , if only for handling I / O errors, etc., but it is not absolutely necessary: ​​you could also catch this exception inside the function and translate them into the return code.

I like how one reporting method from each function, so I (for example) should not try/catch and check return codes.

+2
source share

You are certainly doing the right thing, checking everything before inserting, you should also check if everything you insert is in accordance with the restrictions in your database to avoid an unexpected SQLException, which you don't expect and will go all the way to the top .

I would recommend creating a custom exception with some attributes to describe the cause of the error, so you only need to worry about catching one kind of exception.

In addition, I would definitely put validation inside the method, so it is always called.

+1
source share

A 3-tier approach is fairly common in which you have the following 3 layers:

  • Client interface This might include JavaScript validation for a web application or some basic SWT validation for GUI controls.
  • Business level. This level knows the business rules. Here, as a rule, you will want to perform a server-side check. Everything that needs to be saved, changed, etc., Must be done using the business layer (this way, you always have your own verification and do not care about your data warehouse).
  • Data level. This layer is usually dull. Just save, delete, select, etc .; no matter what business layer requests this layer, it just does it.

This has been greatly simplified, but it gives you a decent way to separate the different types of logic for easier maintenance.

0
source share

Do not put a lot of code in one place. It is also not recommended to throw checked exceptions.

0
source share

All Articles