简体   繁体   中英

Extending functionality of Strategy pattern

I am developing an app that compares files. I decided to use the Strategy design pattern, to handle different formats, so I have something like this:

public class Report {
   CompareStrategy strategy;
   ...
}


public interface CompareStrategy {
   int compare(InputStream A, InputStreamB);
}

Then, naturally I implement the compare method for different file formats.

Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (eg omit a row in case of an Excel or csv file, or omit a node in XML).

Would it be better to:

  1. Add another method to the interface and every implementation (there are few for the moment)
  2. Write a new interface which inherits from CompareStrategy and then implement it?

The second question is: since the differences can be of various types - would it be OK to make a marker interface Difference to enable something like:

int compareWithDifferences(..., Iterable<Difference> differences);

and then go on defining what a difference means for the specific file format?

Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (eg omit a row in case of an Excel or csv file, or omit a node in XML).

Looks like you need the Template Pattern

You can create some abstract class like

public abstract class XMLCompareStrategy implements CompareStrategy {

    public int compare(InputStream A, InputStreamB) {
        // several steps
        customMethod(...);
        // more steps
    }

    protected abstract ... customMethod(...);

}

This way you can create several classes that have the main or core functionality and provide custom details for every situation

The answer really depends on your needs:

  • If the method will always be implemented - add it to the existing interface. If it's only optional - create a new interface that will extend the current one, and then the implemented class could implement either the base interface or the child interface if it needs both methods.
  • For your second question - looks a bit like over-designing to me, but again depends on your needs.

I think you should maybe write another interface that inherit from the CompareStrategy. Like that if you need to compareWithDifferences() you can, but you don't have to use this interface you still can use the simpler one with no differences.

As Jonathan said, if you can foresee difficulties prepare for it. In that case I think you should prepare. Indeed that won't cost you much time to create another interface and you won't have to refactor later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM