Continuing the command pattern, I rejiggered the Save command to use a Backup command rather than hard-coding the backup policy:

public class Save implements IOOperation {
    private final Backup backup;
    private final InputStream newContents;
    private final FuFile original;

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

        this.backup = backup;
        this.newContents = newContents;
        this.original = original;
    }

    public void execute()
            throws IOException {
        backup.prepare(original,
                new Write(newContents, original)).execute();
    }
}

Notice the "prepare" method which is an example of delayed initialization. Since Backup needs a next operation, but Save both needs a Backup and creates the next operation (a Write command), I cannot both create an immutable Backup and create an immutable Save at the same time.

And looking at Backup:

public abstract class Backup implements IOOperation {
    protected final FuPolicy policy;
    private FuFile original;
    private IOOperation next;

    protected Backup(final FuPolicy policy) {
        if (null == policy) throw new NullPointerException();

        this.policy = policy;
    }

    protected FuFile getOriginal() {
        return original;
    }

    protected IOOperation getNext() {
        return next;
    }

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

        this.original = original;
        this.next = next;

        return this;
    }
}

And two implementations:

public class NoBackup extends Backup {
    public NoBackup(final FuPolicy policy) {
        super(policy);
    }

    public void execute()
            throws IOException {
        final FuFile original = getOriginal();

new Delete(original, policy.createScratch(original), getNext()).execute();
}
}


public class SimpleBackup extends Backup {
    public SimpleBackup(final FuPolicy policy) {
        super(policy);
    }

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

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

The second implementation, "SimpleBackup", implements the policy hard-coded previously in Save.

I still use the FuPolicy object to decide how to make a temporary and a backup file. I think that creating a backup should be merged into the Backup object instead, but I haven't decided what the best way to do that is. The problem scenario is an Emacs-scheme multiple backup (e.g., foo.txt, foo.txt.~1~, foo.txt.~2~, etc.). There the policy for naming backups and the backup command are very intimate, and really belong in the same object.


Cheers, --binkley

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



Reply via email to