Skip to content

Instantly share code, notes, and snippets.

@Qkyrie
Created May 15, 2014 09:12
Show Gist options
  • Save Qkyrie/d5d92b2f3c6e280dbd9a to your computer and use it in GitHub Desktop.
Save Qkyrie/d5d92b2f3c6e280dbd9a to your computer and use it in GitHub Desktop.
Specification Pattern
public abstract class AbstractSpecification<T> implements Specification<T> {
protected String messageKey;
public AbstractSpecification(String messageKey) {
this.messageKey = messageKey;
}
public AbstractSpecification() {
this.messageKey = "specification_" + getClass() + "_broken";
}
public abstract boolean isSatisfiedBy(T t);
public Specification<T> and(final Specification<T> other) {
return new AndSpecification<T>(this, other);
}
public Specification<T> or(final Specification<T> other) {
return new OrSpecification<T>(this, other);
}
public Specification<T> not(final Specification<T> other) {
return new NotSpecification<T>(other);
}
@Override
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
public class AndSpecification<T> extends AbstractSpecification<T> {
private Specification<T> spec1;
private Specification<T> spec2;
public AndSpecification(final Specification<T> spec1, final Specification<T> spec2) {
this.spec1 = spec1;
this.spec2 = spec2;
}
public boolean isSatisfiedBy(final T t) {
return spec1.isSatisfiedBy(t) && spec2.isSatisfiedBy(t);
}
}
public class NotSpecification<T> extends AbstractSpecification<T> {
private Specification<T> spec1;
public NotSpecification(final Specification<T> spec1) {
this.spec1 = spec1;
}
public boolean isSatisfiedBy(final T t) {
return !spec1.isSatisfiedBy(t);
}
}
public class OrSpecification<T> extends AbstractSpecification<T> {
private Specification<T> spec1;
private Specification<T> spec2;
public OrSpecification(final Specification<T> spec1, final Specification<T> spec2) {
this.spec1 = spec1;
this.spec2 = spec2;
}
public boolean isSatisfiedBy(final T t) {
return spec1.isSatisfiedBy(t) || spec2.isSatisfiedBy(t);
}
}
public interface Specification<T> {
boolean isSatisfiedBy(T t);
Specification<T> and(Specification<T> specification);
Specification<T> or(Specification<T> specification);
Specification<T> not(Specification<T> specification);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment