Jax Lapusev
Jax Lapusev

Reputation: 63

Strategy with dependency

So a have a class called Dictionary. And one of its' method is

public boolean isRight(String word);

which searches if the word is in the collection of words (that's encapsulated).

private Set<String> rightWords;

So, I want to benchmark different types of searches that's why inside of this method I try to apply Strategy pattern.

public boolean isRight(String word){
        Strategy st = new FastStrategy(word);

        st.search();
        // else...
}

So, since I should look through the rightWords variable should I pass it through the constructor of strategy? But since the raw collection of words is private strategy won't have an access to it.

What should I do?

Also if I pass in a dependency to a strategy does it remain a strategy pattern?

Upvotes: 1

Views: 183

Answers (2)

Costi Ciudatu
Costi Ciudatu

Reputation: 38195

Since those strategies that you want to define are various ways to look up a needle in a haystack, you don't need to keep any state in them.

If you make them stateless, you can provide both the word and the rightWords with every invocation, as method arguments.

As for a way to define them, I would vote for an enum (implementing java.util.function.BiPredicate or some interface of your own if you're not using Java 8):

enum LookupStrategy implements BiPredicate<String, Set<String>> {
    FAST_LOOKUP {
        @Override public boolean test(String word, Set<String> rightWords) {
            return rightWords.contains(word);
        }
    },
    SLOW_LOOKUP {
        @Override public boolean test(String word, Set<String> rightWords) { ... }
    }
}

Then you can make your Dictionary class accept a strategy at construction time (using the interface type, not the actual enum defined above):

class Dictionary {
    private final Set<String> rightWords;
    private final BiPredicate<String, Set<String>> lookupStrategy;

    Dictionary(Set<String> rightWords, BiPredicate<String, Set<String>> lookupStrategy) {
        // initialize private fields
    }

    boolean isRight(String word) {
        return lookupStrategy.test(word, rightWords);
    }
}

Upvotes: 0

Kostas Kryptos
Kostas Kryptos

Reputation: 4111

You can pass your Strategy as input on your isRight() method and it's still a Strategy pattern. Collections.sort() is one of the best examples of Strategy pattern that takes as input a Comparator.

But, you shouldn't initialize your Strategy object with an input Strategy st = new FastStrategy(word);, on the other hand, pass the String word as input to your search() method. For instance:

public boolean isRight(String word, Strategy st){
    ..
    st.search(word);
    // else...
}

Upvotes: 1

Related Questions