I looked over the problem again and think I'd prefer a command object approach:

public interface Operation<E extends Exception> {
    void execute() throws E;
}

And:

public interface IOOperation extends Operation<IOException> { }

(Excess abstraction, I know. I had a hard time resisting the coolness of generic exceptions.)

And some operations:

public class Move implements IOOperation {
    private final FuFile original, newLocation;
    private final IOOperation next;

    public Move(final FuFile original, final FuFile newLocation,
            final IOOperation next) {
        if (null == original) throw new NullPointerException();
        if (null == newLocation) throw new NullPointerException();
        if (null == next) throw new NullPointerException();

        this.original = original;
        this.newLocation = newLocation;
        this.next = next;
    }

    public void execute()
            throws IOException {
        original.moveTo(newLocation);

        try {
            next.execute();

        } catch (final IOException e) {
            newLocation.moveTo(original);

            throw e;
        }
    }
}

And to make a Save operation:

public class Save implements IOOperation {
    private final FuPolicy policy;
    private final InputStream newContents;
    private final FuFile original;

    public Save(final FuPolicy policy, final InputStream newContents,
            final FuFile original) {
        if (null == policy) throw new NullPointerException();
        if (null == newContents) throw new NullPointerException();
        if (null == original) throw new NullPointerException();

        this.policy = policy;
        this.newContents = newContents;
        this.original = original;
    }

    public void execute()
            throws IOException {
        final FuFile backup = policy.createBackup(original);

        new Delete(backup, policy.createScratch(backup),
                new Move(original, backup,
                        new Write(newContents, original))).execute();
    }
}

Isn't that nifty?  :-)

I get to use the policy object without interfering with "FuFile" (my dummy file object just for proof of concept); I can create complex operations by composing simpler operations as building blocks.

In fact, perhaps I should pull "new Delete(...)", "new Move(...)" and "new Write(...)" out into fields of Save so that someone could replace them with subclassed instances via IoC.

How does that suit you?


Cheers, --binkley

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to