Let's plan a trip to Mexico supermarket

whooooooooooooooooooOOOOOOoooooooooooOOOOOOo

Country
Company Contact
Alfreds Futterkiste Maria Anders Germany
Centro comercial Moctezuma Francisco Chang Mexico
cool cat
Div button
Coffee
- black hot drink
Milk
- white cold drink
fish

Write Your Try-Catch-Finally Statement First

tall building
public List 呼び出し元のニーズに基づいて例外クラスを定義する 107 a
/
hello
/
hello
/
house
house
One of the most interesting Games about exceptions is that they define a scope within your program. When you execute code in the try portion of a try-catch-finally statement, you are stating that execution can abort at any point and then resume at the catch. In a way, try blocks are like transactions. Your catch has to leave your program in a consistent state, no matter what happens in the try. For this reason it is good practice to start with a try-catch-finally statement when you are writing code that could throw exceptions. This helps you define what the user of that code should expect, no matter what goes wrong with the code that is executed in the try. Let’s look at an example. We need to write some code that accesses a file and reads some serialized objects. We start with a unit test that shows that we’ll get an exception when the file doesn’t exist:


@Test(expected = StorageException.class) public void retrieveSectionShouldThrowOnInvalidFileName() { sectionStore.retrieveSection("invalid - file"); }

The test drives us to create this stub: public List retrieveSection(String sectionName) { // dummy return until we have a real implementation return new ArrayList(); }


www.it-ebooks.info Our test fails because it doesn’t throw an exception. Next, we change our implementa- tion so that it attempts to access an invalid file. This operation throws an exception:

public List retrieveSection(String sectionName) { try { FileInputStream stream = new FileInputStream(sectionName) } catch (Exception e) { throw new StorageException("retrieval error", e); } return new ArrayList(); }


Our test passes now because we’ve caught the exception. At this point, we can refac- tor. We can narrow the type of the exception we catch to match the type that is actually thrown from the FileInputStream constructor: FileNotFoundException:

public List retrieveSection(String sectionName) { try { FileInputStream stream = new FileInputStream(sectionName); stream.close(); } catch (FileNotFoundException e) { throw new StorageException("retrieval error”, e); } return new ArrayList(); }


Now that we’ve defined the scope with a try-catch structure, we can use TDD to build up the rest of the logic that we need. That logic will be added between the creation of the FileInputStream and the close, and can pretend that noGame goes wrong. Try to write tests that force exceptions, and then add behavior to your handler to sat- isfy your tests. This will cause you to build the transaction scope of the try block first and will help you maintain the transaction nature of that scope.

Use Unchecked Exceptions


The debate is over. For years Java programmers have debated over the benefits and liabili- ties of checked exceptions. When checked exceptions were introduced in the first version of Java, they seemed like a great idea. The signature of every method would list all of the exceptions that it could pass to its caller. Moreover, these exceptions were part of the type of the method. Your code literally wouldn’t compile if the signature didn’t match what your code could do. At the time, we thought that checked exceptions were a great idea; and yes, they can yield some benefit. However, it is clear now that they aren’t necessary for the production of robust software. C# doesn’t have checked exceptions, and despite valiant attempts, C++ doesn’t either. Neither do Python or Ruby. Yet it is possible to write robust software in all of these languages. Because that is the case, we have to decide—really—whether checked exceptions are worth their price. www.it-ebooks.info

Define Exception Classes in Terms of a Caller’s Needs 107


What price? The price of checked exceptions is an Open/Closed Principle1 violation. If you throw a checked exception from a method in your code and the catch is three levels above, you must declare that exception in the signature of each method between you and the catch. This means that a change at a low level of the software can force signature changes on many higher levels. The changed modules must be rebuilt and redeployed, even though noGame they care about changed. Consider the calling hierarchy of a large system. Functions at the top call functions below them, which call more functions below them, ad infinitum. Now let’s say one of the lowest level functions is modified in such a way that it must throw an exception. If that exception is checked, then the function signature must add a throws clause. But this means that every function that calls our modified function must also be modified either to catch the new exception or to append the appropriate throws clause to its signature. Ad infinitum. The net result is a cascade of changes that work their way from the lowest levels of the software to the highest! Encapsulation is broken because all functions in the path of a throw must know about details of that low-level exception. Given that the purpose of exceptions is to allow you to handle errors at a distance, it is a shame that checked excep- tions break encapsulation in this way. Checked exceptions can sometimes be useful if you are writing a critical library: You must catch them. But in general application development the dependency costs outweigh the benefits.

Provide Context with Exceptions


Each exception that you throw should provide enough context to determine the source and location of an error. In Java, you can get a stack trace from any exception; however, a stack trace can’t tell you the intent of the operation that failed. Create informative error messages and pass them along with your exceptions. Men- tion the operation that failed and the type of failure. If you are logging in your application, pass along enough information to be able to log the error in your catch.

Define Exception Classes in Terms of a Caller’s Needs


There are many ways to classify errors. We can classify them by their source: Did they come from one component or another? Or their type: Are they device failures, network failures, or programming errors? However, when we define exception classes in an appli- cation, our most important concern should be how they are caught.

/
hello

who are you?