Last active
July 26, 2016 05:21
-
-
Save adamv/8eef51f55b5ecefdbb103e012120c139 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package codenotes; | |
public class Main { | |
public static void main(String[] args) { | |
Result r = new Result(Result.FIRST_NAME_FLAG|Result.LAST_NAME_FLAG|Result.ADDRESS_FLAG); | |
Result.Match m1 = Result.Match.atLeast().firstName().lastName(); | |
System.out.println(r.matches(m1)); // true | |
Result.Match m2 = Result.Match.exactly().firstName().lastName().address(); | |
System.out.println(r.matches(m2)); // true | |
Result.Match m3 = Result.Match.exactly().firstName().lastName(); | |
System.out.println(r.matches(m3)); // false | |
Result.Match m4 = Result.Match.atLeast().firstName().phone(); | |
System.out.println(r.matches(m4)); // false | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package codenotes; | |
import java.util.Objects; | |
/** | |
* A service result. | |
* | |
* A result can match on lots of different stuff, so introduce a Match | |
* class that allows clients of this code to query what was matched on. | |
*/ | |
public class Result { | |
public static int FIRST_NAME_FLAG = 1; | |
public static int LAST_NAME_FLAG = 2; | |
public static int ADDRESS_FLAG = 4; | |
public static int PHONE_FLAG = 8; | |
/** | |
* Match instances are immutable and contain their own builder. To | |
* construct one, start with `atLeast()` or `exactly()` and chain the | |
* methods corresponding to the stuff that you want to match. | |
*/ | |
public static class Match { | |
boolean matches(int matchedThings) { | |
switch (mode) { | |
case AT_LEAST: | |
return (matchedThings & flags) == flags; | |
case EXACTLY: | |
return matchedThings == flags; | |
default: | |
throw new IllegalStateException("Illegal match mode " + mode); | |
} | |
} | |
enum Mode { AT_LEAST, EXACTLY } | |
private final Mode mode; | |
private final int flags; | |
Match(Mode mode, int flags) { | |
Objects.requireNonNull(mode); | |
this.mode = mode; | |
this.flags = flags; | |
} | |
public static Match atLeast() { | |
return new Match(Mode.AT_LEAST, 0); | |
} | |
public static Match exactly() { | |
return new Match(Mode.EXACTLY, 0); | |
} | |
public Match firstName() { | |
return new Match(this.mode, this.flags | FIRST_NAME_FLAG); | |
} | |
public Match lastName() { | |
return new Match(this.mode, this.flags | LAST_NAME_FLAG); | |
} | |
public Match address() { | |
return new Match(this.mode, this.flags | ADDRESS_FLAG); | |
} | |
public Match phone() { | |
return new Match(this.mode, this.flags | PHONE_FLAG); | |
} | |
} | |
private final int matchedThings; | |
public Result(int matchedThings) { | |
this.matchedThings = matchedThings; | |
} | |
public boolean matches(Match match) { | |
return match.matches(this.matchedThings); | |
} | |
} |
A more by-the-book approach would replace the Mode
enum and switch statement with two subclasses, but let's not get hung up on the details here.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Defining
boolean matches(int flags)
onResult
seems simpler to me, but in case I need to embiggen the interface...