23
PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Embed Size (px)

Citation preview

Page 1: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

PRAGMATIC PARANOIA

Steven Hadfield & Anthony Rice

Page 2: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

You can’t write perfect software Accept it Nobody else writes it either

Be defensive about other people’s code Play it safe

Page 3: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Design by Contract

Developed by Bertrand Meyer (Eiffel) Use contracts to force both parties into

an agreement: caller and routine Each party is expected to uphold their

end of the deal Preconditions, postconditions, and class

invariants

Page 4: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Preconditions

What the caller guarantees will be passed to the routine

The routine’s requirements It’s up to the calling code to make sure

that the requirements are kept

Page 5: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Postconditions

What the routine guarantees to return How the world should be after the

routine is done Lazy code: require a lot, promise little in

return

Page 6: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Class invariants

Conditions that should always be true from caller’s perspective

Routine possibly allowed to change it temporarily while working, but should return to previous state

Things that the routine is not allowed to change

Applies to all methods in a class

Page 7: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Designing with Contracts

It’s a design technique Directly supported by some languages Handy if compiler can do it, but not

necessary Assertions – partially emulate DBC Use preprocessors for languages without

Messy and not as good, but helpful Can be dynamically generated

Rejected and/or negotiated

Page 8: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Invariants

Also applies at lower levels Loop invariant

Making sure something is true before and during a loop

Semantic invariants Central to the purpose of a task Should be clear and unambiguous

Page 9: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Dead Programs Tell No Lies

If a program is going to crash, do it early Crash with class

Provide useful information If the impossible happens, die as soon as

possible Everything after the impossible happens is

suspect

Page 10: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Assertive Programming

This can never happen… “This code will not be used 30 years from

now, so two-digit dates are fine” “This application will never be used abroad,

so why internationalize it?” “count can’t be negative” “This printf can’t fail”

Page 11: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Assertions

If it can’t happen, use assertions to ensure that it won’t

Don’t use assertions as error handling, they should just be used to check for things that should never happen.

Void writeString(char *string){assert(string != NULL);

Never put code that should be executed into as assert.

Page 12: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Leave Assertions Turned On

Misunderstanding: Since they check for things that should

never happen, the are only triggered by a bug in the code. They should be turned off when shipped to make the code run faster.

Page 13: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Leave Assertions Turned On

You cannot assume that testing will find all the bugs.

Your program runs in a dangerous world. Your first line of defense is checking for

any possible error, and your second is using assertions to try to detect those you missed.

Page 14: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Assertions and Side Effects

Instead of: While (iter.hasMoreElements()) {

Test.ASSERT(iter.nextElement() != null);

Object obj = iter.nextElement(); Do:

While (iter.hasMoreElements()) {Object obj = iter.nextElement();Test. ASSERT(obj != null);

Page 15: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

When to Use Exceptions

Checking for every possible error can lead to some pretty ugly code.

If the programming language supports exceptions, you can use try catch loops to make the code much easier to read.

Page 16: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

What is Exceptional?

Exceptions should be reserved for unexpected events.

They should rarely be used as the programs normal flow.

Page 17: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Use Exceptions for Exceptional Programs

An exception represents an immediate, nonlocal transfer of control.

Using exceptions as part of normal processing will give you all the readability and maintainability problems of spaghetti code.

Page 18: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Error Handlers Are an Alternative Error Handlers are routines that are

called when an error is detected. These routines can handle a specific

category of errors.

Page 19: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

How to Balance Resources

Finish What You Start Many developers have not consistent plan

for dealing with resource allocation and deallocation.

The routine or object that allocates a resource should be responsible for deallocating it.

Page 20: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Nest Allocations

The basic pattern for resource allocation can be extended for routines that need more than one resource at a time. Deallocate resources in the opposite order

in which you allocate them. When allocating the same set of resources

in different places in your code, always allocate them in the same order.

Page 21: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Objects and Exceptions

Encapsulation of resources in classes Instantiate that class when you need a

particular resource type.

Page 22: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

When You Can’t Balance Resources Commonly found in programs that use

dynamic data structures. When you deallocate the top-level data

structure: Top-level structure responsible for

substructures. Top-level structure is simply deallocated. Top-level structure refuses to deallocate

itself if it contains substructures. Choice depends on individual data

structure.

Page 23: PRAGMATIC PARANOIA Steven Hadfield & Anthony Rice

Checking the Balance

Produce wrappers for each resource, and keep track of all allocations and deallocations.

When program logic says resources will be in a certain state you can use the wrappers to check it.