December 2006

Epigrams on Programming

Just ran across Alan Perlis’s Epigrams on Programming:

This one goes with my recent rant on interfaces:

The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information.

Design
General
Software Development
Thought

Comments (0)

Permalink

Books!

Books to the ceiling,/ Books to the sky,/ My pile of books is a mile high./ How I love them! How I need them!/ I’ll have a long beard by the time I read them.
- Arnold Lobel

Sunday was my 30th birthday. So, I went out and got me some birthday presents:

I picked up Domain-Driven Design: Tackling Complexity in the Heart of Software
by Eric Evans. Blaine had lent me his copy, and has been telling me for the longest time that I needed to pick this one up. So I did. I got about 25% of the way thru the first time before giving it back to Blaine, so I am looking forward to finishing it.

I also picked up Refactoring to Patterns (The Addison-Wesley Signature Series) by Joshua Kerievsky. This one has been on my wishlist for a long time. I have skimmed the first few chapters and it looks great.

The non-tech book I am currently reading is The Way of Zen by Alan Watts. I have had this book for quite some time now. Before this time, every time I tried to read it I would get bogged down in the sometime terse language. This time I got through that and now am throuroughly enjoying it, although it still can be difficult at times with the Chinese and Indian names for things.

Books
Design
General
Software Development
Thought

Comments (3)

Permalink

Porous interface design

Which do you think is better?

this:

  1. public interface Scheduler {
  2.   // schedule job to deliver the domain object represented by the domainId at scheduleDate
  3.   public void scheduleDeliver(Long domainId, Date scheduleDate);
  4.   public void scheduleReprocess(Long domainId, Date scheduleDate);
  5.   …
  6.   public void scheduleCleanUp(Long domainId, Date scheduleDate);
  7. }

or this:

  1. public interface Scheduler {
  2.   // schedule a job
  3.   public void schedule(Date runAt, Job job);
  4. }

I would say “It depends, what is in the Job class?”

  1. public interface Job {
  2.   public void run();
  3. }

Heh, ok so its an interface. What is the implementation?

  1. public class DeliveryJob implements Job {
  2.   public DeliveryJob(/* context */) {}
  3.   public void run() {
  4.       // delivery code here.
  5.   }
  6. }

Which gives you this client code:

  1. public void someMethod() {
  2.   …
  3.   SchedulerImpl.schedule(runAt, new DeliveryJob(/* context can be passed in here */));
  4.   …
  5. }

But also allows for the implementation of closures:

  1. public void someMethod() {
  2.   …
  3.   SchedulerImpl.schedule(runAt, new Job() {
  4.       // code goes here.
  5.       // context in final variables in outer "someMethod"
  6.   });
  7.   …
  8. }

Ok, so there are two different interfaces, both ostensibly providing a mechanism to schedule something to run at a later date/time. Which is better? Lets look at each in turn.

The first one is using primatives to represent the data needed for the scheduling contract, in this case a Long for a “domainId” and a Date for the “scheduledDate” to run at. Each method specifies what type of job needs to be scheduled (”scheduleDelivery”, “scheduleReplay”, etc). On the immediate surface, there is nothing that stands out as a major issue. Now, lets think about how this will need to be maintained:

  • Lets say you need to change the domainId from a Long to a “DomainKey” object. This is a huge change, of which the Scheduler interface is going to see only minor changes from, but will cause rippling effects throughout both the client and the implementation code.
  • What if you want to allow a different type of job to be scheduled? You would need to add a new interface method and a new implementation.
  • The interface leaves you (or at least me) with the impression that I would need to keep the interface pretty consistent to maintain clarity. That means that anytime I wanted to schedule some new thing, I would feel compelled to propagate the interface as it is currently implemented. If I needed to do anything that seemed inconsistent I would hesitate, and probably end up with an implementation different than I initially wanted.

The second one uses an Interface to provide the job implementation. This helps to abstract the Scheduler from the implementation details of the job. By not tying into the implementation details, it keeps it’s Single Responsibility clear: to run the given job at the given time.

The only “problems” that this implementation has is that it creates extra classes, and has the ability to be “abused” by using anonymous inner classes. Notice the use of quotations in the prior sentence to indicate the facetiousness of this argument. Surprisingly, I’ve heard this argument so many times, both directly and indirectly. In this case the argument is groundless, as there is very little in the way of extra classes; just an interface and a class per implementation. This is no big deal, and is completely outweighed by the simplicity of the design.

Another argument that I have heard with this type of discussion is that the only data needed is the primitives, so why not just send that? Well, there are a number of reasons not to do that. The first is that the primitives do not represent your domain… they are an abstraction of your domain, which is an abstraction itself. I generally prefer to keep my sanity.

The one argument I could see holding water against the second interface is if it is desirable to have a domain centered interface for scheduling these jobs. But, in this case, the solution is not to get rid of the current Scheduler interface, but to add a Domain Specific Scheduler interface:

  1. public interface DomainScheduler {
  2.   public void scheduleDelivery(Date runAt, DomainObject do);
  3.   …
  4. }

Notice that even this new interface stays away from the primitive Long domainId field from the first interface. This reduces the problems from the first interface:

  • Now, a change to the key would not require an interface change, and depending on the implementation, it may not need to change either. The client code is obviously not affected.
  • It is clearer what you are doing with the data. Even if the underlying implementation does the exact same thing, now you are not wondering why only the id field is needed.

The final two interfaces are examples of porous interface design. They allow for wider ranges of data to go through, but without the worry of incorrect data, or providing too much data (Why would you allow Object?). They also make the system more extensible without changing any of the existing code. By keeping things centered around the domain, and the Single Responsibility Principle in mind, you end up with a much simpler, more maintainable design.

Design
General
Java
Ruby
Software Development
Thought

Comments (2)

Permalink

When to use inheritance

I was just perusing my copy of Java Design: Building Better Apps and Applets by Peter Coad and Mark Mayfield and noticed a good set of rules to follow when thinking about using inheritance:

  1. “Is a special kind of”, not “is a role played by a”
  2. Never needs to transmute to be an object in some other class
  3. Extends rather than overrides or nullifies superclass
  4. Does not subclass what is merely a utility class (useful functionality you would like to reuse)
  5. Within PD(Problem Domain): expresses special kinds of roles, transactions, or devices

Update: I probably should mention that you should fulfill all or at least most of these to consider inheritance. Otherwise use composition or re-analyze your design.

General
Java
Ruby
Software Development

Comments (0)

Permalink

Changing Mindset: From Procedural to Object Oriented

Yesterday I had the chance to write some code to determine if I needed to schedule an action for later processing, or do the action immediately. I am working on a system that has a fairly well laid out component architecture, with a fairly good Business model. However, it is almost all “Controllers and Data Structures” at this point. Given my previous experiences with how people would write this type of code, it would invariably end up like this:

  1. public void someComponentMethod(Long rootModelID) {
  2.   RootModelObject root = DAOFactory.getRootModelDAO().getRootModel(rootModelID);
  3.  
  4.   // many lines of code later …
  5.  
  6.   if ( root.getExtraData() != null &&
  7.         root.getExtraData().getSchedule() != null ) {
  8.         Schedule s = root.getExtraData().getSchedule();
  9.         if ( s.getScheduleDate().after(new Date()) ||
  10.              s.getCronExpression() != null ) {
  11.                 root.setStatus(SCHEDULED);
  12.                 DAOFactory.getRootModelDAO().save(root);
  13.                // schedule for later code
  14.         }
  15.   } else {
  16.         // deliver immediately code
  17.   }
  18.   // many lines of code later …
  19. }

There are a number of issues in the above code:

  1. The interface to this method is abhorrent. I will discuss this in another post.
  2. The component knows WAY too much about the specifics for processing.
  3. Hand in hand with the above, it knows way too much about the Business Model.

This is a classic case of “Asking, not Telling”, the antithesis to the awesome article Tell, Don’t Ask, by Dave Thomas and Andy Hunt. GO NOW and read it if you haven’t.

Here is the code I ‘ve written so far:

  1. public void someComponentMethod(RootModelObject root) {
  2.         // small amount of other code
  3.  
  4.         if ( root.shouldBeScheduled() ) {
  5.                 root.setStatus(SCHEDULED);
  6.                 DAOFactory.getRootModelDAO().save(root);
  7.                 scheduleComponent.schedule(root);
  8.         }
  9.         else {
  10.                 root.setStatus(PROCESSING);
  11.                 DAOFactory.getRootModelDAO().save(root);
  12.                 nextComponent.process(root);
  13.         }
  14. }

There are few things here that are better: First, I pass in the object I want to work on… this is SO much better than having to go get the Object from some back-end store by ID. I will definitely be talking about this more in the near future. Second, I broke out the beautiful comments from the code above into separate methods, on the components that they represent. This can only make things easier in that code, which most assuredly would have otherwise been in the if block as the comments suggest. And finally the piece that got me started on this post, I moved all of the logic revolving around the Schedule behind the walls of the RootModelObject. But, I did not stop there. Since from the perspective of the RootModelObject, it is not it’s responsibility to determine if it should be scheduled, I created a shouldBeScheduled method on the ExtraData object, which then called a shouldBeScheduled() method on the Schedule object:

  1. class RootModelObject {
  2.   …
  3.   public boolean shouldBeScheduled() {
  4.         return getExtraData().shouldBeScheduled();
  5.   }
  6. }
  7.  
  8. class ExtraData {
  9.   …
  10.   public boolean shouldBeScheduled() {
  11.         return getSchedule().shouldBeScheduled();
  12.   }
  13. }
  14.  
  15. class Schedule {
  16.   …
  17.   public boolean shouldBeScheduled() {
  18.         return ( getScheduleDate().after(new Date()) ||
  19.                    getCronExpression() != null );
  20.   }
  21. }

This “string of pearls” makes it much easier to keep the code where it needs to be, while providing convenience to the component developer.

So, the code is better, but part of me says that the code really should look like this:

  1. public void someHigherLevelComponentMethod(RootModelObject root) {
  2.   …
  3.   root.schedule();
  4. }

Since technically, when you say “process immediately” you are effectively saying “schedule for processing now”. What do you think?

Books
General
Java
Software Development
Thought

Comments (2)

Permalink