Daniel Pitts’ Tech Blog

Posts Tagged ‘design’

Exceptional Exceptions!

Monday, July 21st, 2008

First, some boring philosophy about exceptions, then some interesting ways to circumvent the checked exception mechanism.

When designing your system, you should decide carefully which type of exception you want to throw. You have basically three choices: Errors, Exceptions, or RuntimeExceptions.

For unchecked exceptions, generally Errors shouldn’t be thrown directly, and RuntimeExceptions should be thrown (only) if the programmer could have prevented the exception before hand. This last point is arguable, but as a rule of thumb, works pretty well.

Checked exceptions should be used when a condition might occure, outside the programmers control, that isn’t what a typical work-flow would expect.  Check exceptions, if they can’t be dealt with, should bubble up to a user in an appropriate way.  The user should then be given an opportunity to decide what to do, such as retry the operation, report a bug, or go eat lunch and forget about it :-)

Now comes the interesting part. Circumventing checked exceptions.

There are at least two ways to throw a checked exception that isn’t actually checked.  Like with most of my esoteric Java features, they shouldn’t be used in production code. Both are hacks and both are ugly.

The first approach:  Class.newInstance().  Class.newInstance() will propagate any exceptions from the constructor to the calling code.  If your constructor throws a check exception, it will leak from Class.newInstance();

import java.io.IOException;
public class NoChecked1 {
   NoChecked1() throws IOException { throw new IOException("Leaked!"); }
   public static void main(String...args) {
      try {
          NoChecked1.class.newInstance();
      } catch (InstantiationException e) {
      } catch (IllegalAccessException e) {
      }
   }
}

The second approach: Thread.stop(Throwable t). stop(Throwable t) was deprecated a while ago, but Thank God Java Is Backward Compatible. calling this overload of stop will cause the thread to spontaneously throw an exception, checked or otherwise.

import java.io.IOException;
public class NoChecked1 {
   public static void main(String...args) {
      Thread.currentThread().stop(new IOException("Leaked again"));
   }
}

Yikes. Don’t try this at home kids.

The Art of Decoupling.

Monday, December 3rd, 2007

Some people think the power of OO design is that the classes represent real-life concepts that are easier for a human to understand. Others think that its power comes from code reuse. Still other just accept OO as the paradigm that they are supposed to use, simply because they were told so.

The truth is that using any of those approaches to design may well leave you with a brittle, unmanageable, ugly mess. Personally, I strive for the “real-life concepts” as one top-level goal. The other top level goal is decoupling. Transcending all goals, of course, is creating a “correct” program. Not necessarily “correct” in the academic sense. I don’t verify every algorithm I use, and I don’t necessarily determine valid pre/post conditions. I mean correct in as much as, it works for what I need it to work for.

For small programs, this is pretty easy. When you get to larger systems, this becomes a slightly different problem to solve. In the days of goto, spaghetti code arose due to poor organization and ad hoc control transfer. Structured programming helped some by organizing the control codes into a set of well-defined idioms. Object oriented programming helped further by organizing responsibility into encapsulated modules. All of these paradigms had something in common; you could write brittle code or malleable code in any one of them. Granted, writing flexible code has gotten easier with Object Oriented programming, but only if you know what makes code brittle.

Over dependence of one section of code on another section of code. In software engineering, we call this coupling. If the behavior of A is dependent on the behavior of B, then A is dependent on B. Changing the behavior of B could change the behavior of A. This isn’t always a bad thing, but if A and B are written by different people (or the same person at different times) with different goals, it could be catastrophic. It isn’t always feasible to decouple two classes, or two methods, or even two lines of code, but if you can do it easily, consider what might be gained by that.

One syndrome I’ve noticed is that with any concept, some people take it to the extreme. For those readers who stopped at the above paragraph and decided I was right, and everything should be as decoupled as possible, you might see a design that I would call disintegrated. It is possible to create code that is so decoupled as to be impossible to figure out how one thing affects another, even though the overall system is design for A to affect B. Don’t do this :-)

One approach to decoupling two classes is to have them communicate through an event system. This will couple them both to the event system, but not to eachother. This approach allows you to replace one of the pair without changing the other side at all. This makes a lot of sense for GUI applications, for example, where user interactions with the component (such as a button) generates an event that can be handled very differently, depending on the needs of the program. Most object oriented languages, and Java in particular, already has a useful mechanism for invoking behavior on other objects. Its called method invocation, the act of making a method call. Event systems are useful for decoupling the method call from the class that needs to know about the call, its not so useful as a replacement for normal method invocation.

There are plenty of other ways to decouple you code (often through use of patterns), but I won’t get into them here. GIYF

Software design is about making difficult choices. If you didn’t have to make choices, then it would be easy to create a simple program that can design software. Your job as an engineer is to decide what should be decoupled from what. Decoupling can be a great tool to create a reusable component, but not everything should be designed to be reusable. If you’ve written something that was coupled, but needs to be made reusable… Well, thats what refactoring is for. Decoupling two classes that only communicate with each other can actually add complexity for that use case, so unless you strongly believe that at least one of the two classes will be useful in other situations, it is a waste of cognitive power to separate them.

My goal for production-quality software design? Create the simplest design that meets all my requirements, but is flexible enough to adapt to future requirements.

Primitive Obsession II: (Im)mutability and Redefining Primitive

Sunday, November 4th, 2007

Last week I discussed some of the techniques for and benefits of not using simple “Primitive” values to represent your data. This article is all about taking that concept to the next level.

Let’s say that I have a value that represents an angle. I could use a double to represent the radians, or I could create a class called Angle, which internally might use a double to represent radians. If you are trying to avoid primitive obsession, you would use the latter. Now you have value objects of type Angle which can be used in meaningful ways. So, we’re done, right? I say no.

Angle is now its own form of primitive. Just as an Integer object is an abstraction of a numeric value in a specific set of reals, an Angle instance is an abstraction of a geometric/trigonometric angle. This means that it can be the building block for other more specific types. For instance, a 2 dimensional vector can be represented in “polar form” as an Angle and a Magnitude. In a physical simulation, a Magnitude is often a Distance, so we’ll assume that case for this article.

So, we can create a Vector interface (not to be confused with the java.util.Vector class). We can then create a PolarVectorImpl class which uses Angle and Distance. We can even create a CartesianVectorImpl which uses two Distance objects to represent the vector. Whats more, is these can both be used by anything that expects a Vector, with no extra work in the client code. We can easily create a rotate(Angle) method, or any other useful methods.

Another important and related concept that we haven’t touched on is mutability. If an object is mutable, that means that the apparent state of the object can change over the lifetime of the object. If an object is immutable, the apparent state of the object will appear the same throughout the lifetime of the object. This means that any invocation of one method on that object will always have the same outcome as any other on that same method. Also, any object that is returned from those methods must either be immutable themselves, or be distinct instances. Why is this important? Immutable objects have some benefits.

  • Immutable objects are inherently thread safe.
  • Immutable objects are easy to reason about.
  • Immutable objects are easier to debug.
  • Immutable objects can be passed around freely without defensive copying.

On the down side, immutability makes a pretty boring universe. If you’re object is expected to do different things depending on what has happened to it in the past, that object must be mutable. It must have state.

What does this have to do with primitive values? Its common to create immutable value objects. If we design the Angle class to be immutable, then we can safely say that one instance represents exactly one angle throughout its lifetime. All of our Angle objects are value objects. They are utility objects and reusable in many projects. On the other hand, if we’re doing a simulation of sorts, it might be useful to have a mutable angle, something that we can adjust over time. Lets call this class Heading. What’s in a Heading? An Angle, of course. Now here’s where things get interesting…

Since an Angle is a measurable thing, its easy to compare two values for equality. For Angles specifically, they are equal if their values represent the same geometric angle. Once equality is established, those objects are equal for ever. Not so with Heading. A Heading may represent the same angle at one moment in time, but at another moment they represent very different angles. For this type of object, equality only makes sense for the identity. A Heading instance is its own object, and can be queried/manipulated by many other objects/methods within the project.

The benefit of this design, is a manipulator/querier need not know who “owns” the Heading instance. A Robot might have a Heading, and a SteeringServo might manipulate that Heading. You can create the Robot and the SteeringServo objects independently of each other. The SteeringServo doesn’t even need to know its the Heading of a Robot. Once the Robot and SteeringServo both have the same Heading instance, they become connected without being coupled. This is huge goal for Object Oriented designers/programmers. The correct functioning of a SteeringServo isn’t dependent on the correct functioning of a Robot, or even of a Heading, only on itself. Similarly, a Robot’s correct functioning isn’t dependent on the correct functioning of the SteeringServo. The program as a whole may not work if there is a bug, but it easier to look at one class and ask yourself “Is there anything wrong with this code,” than it is to ask the same question about the whole project.

If you think all of this abstraction is unnecessary or unhelpful, think about all the layers beneath our Heading class. Lets have some fun and break it down into its most primitive parts.

  • Heading instance is an identity value containing an Angle and representing a direction at a point in time.
  • An Angle is an equal-comparable value containing a double and representing a direction.
  • A double is a equal-comparable and order-comparable value containing an ordered set of bits and representing a real number.
  • A bit is an equal-comparable value containing a memory cell representing true or false.
  • A memory cell is often times a capacitor that is either charged or uncharged

If you had to think about the implementation details of a bit every time you used a double, it would make the mental weight of programming so immense that no useful programs could be written. Heading can now be used very easily without adding the mental weight of how its implemented. SteeringServo can be implemented without the mental weight of what it is steering. Overall, the practice of this kind of decoupling will make your program easier for the most important source-code interpreter. You.

The Dangers of Reflection: Or, Put Down That Mirror!

Thursday, January 11th, 2007

I want to start out by saying that reflection in itself isn’t a Bad Thing™. It is just one of those things that tends to be oft abused. I should know, since I’ve abused it more often than I care to admit.

To put things in perspective, let me list some examples of well designed projects that use reflection.

JUnit
JUnit uses reflection to ease the creating of individual tests. A test writer can add a test simple by creating a public void method with a name that starts with “test”. This allows you to write many distinct tests without having to “wire up” the tests manually. They get executed by virtue of naming convention.
The Spring Framework
The Spring Framework is actually a collection of many different “tools”. Its guiding principal is to help software engineer better design thier systems to use the Inversion of Control pattern. There are many different parts of Spring that use reflection to aid with IoC, so I’ll just name one example. Spring allows you to define an application context in XML. The application context allows you to inject dependencies, so that class implementations don’t have to care about where their dependencies come from. Its almost obvious that reflection is the cleanest way to handle any java object in abstract ways. Without reflection, you would have to litter your code with Spring specific interfaces and implementation details. Ick!
Hibernate
Hibernate is used to map data between object models and relational models. In other words, its used as the bridge between Java and SQL. The latest versions of Hibernate allow you to create your database structure based on your JavaBean classes. It uses reflection (and proxies) to automate translation to and from relational data.

There are a few more well-designed projects that use reflection, but lets look at what seems to be a common thread.
JUnit is a general-purpose testing framework. Spring is a general-purpose IoC framework. Hibernate is a general-purpose ORM framework.

See a pattern?
Reflection is well suited for general purpose frameworks. Its used when polymorphism just won’t cut the bill.


So, what abuses of reflection have I seen? I have to admit, and I’m ashamed, they are mostly ones I’ve committed.
—-
One of the more “interesting” classes I’ve created is the DelegateMap. The DelegateMap implements java.util.Map, and allows you to “connect” a bean object to it. This means the map becomes a view of the bean. if you call map.put(”propertyName”, value), it will actually update the bean. if you call map.get(”propertyName”), it will return the value held by the bean’s property. Sound like a useful gizmo? I won’t say it isn’t useful, but it is a bit more error prone than I would have liked.

map.putAll(otherMap) is an interesting use of this class. At first glance, it looks like you can copy one bean to another, without worrying about individual properties. assert !book.getCover().judged(); An interesting note about the JavaBean spec, is that by default, all objects have a property called “class” {see Object.getClass()}. This property is read-only (imagine trying to implement strong-typing in an environment where the type can change at will!). delegateMap.putAll(otherDelegateMap) will throw an exception when it tries to set the read-only property “class”.

The other danger of this class is that it breaks refactoring. Simple automatic refactoring, such as IntelliJ IDEA’s “rename”, should change the source of a project without changing the behavior. If you have two objects that aren’t related other than through naming convention on the property name, it becomes conceivable to break a “delegate map copy operation” simply by changing the name of one property in either class. Whats worse is your compiler will not notice, and your tests may not warn you in time.
—-
I’ve found myself refactoring away from introspection and reflection time after time. Inversion of Control is my usual destination pattern. Using polymorphism over reflection, I find that my design is cleaner and my code more easily understood. I also find that I have far fewer exceptions in my log files.

If I may make an analogy, reflection is a high-temperature cutting-torch, and we usually just need to cut some paper. Use with caution, and wear some safety goggles.