This article is excerpted from This is How Design Patterns should Be Learned

1 Specification mode definition

Specification Pattern can be considered as an extension of composite Pattern. Many times certain conditions in the program determine the business logic, and these conditions can be isolated and combined in some relationship (and, or, or not) to flexibly customize the business logic. In addition, in applications such as query and filtering, you can simplify the implementation logic by pre-defining multiple conditions and then using the combination of these conditions to process the query or filtering instead of using logical judgment statements. Each condition is a specification, and several specifications (conditions) are connected in series to form a combined specification in some logical relationship. Specification pattern belongs to structural design pattern.

2 Application scenarios of the specification mode

The specification mode applies to the following application scenarios.

(1) Verify the object to check whether the object itself meets some business requirements or is ready to achieve a certain business goal.

(2) Select objects or subsets of objects from the collection that conform to specific business rules.

(3) Specify that some business requirement must be met when creating a new object.

UML class diagrams for specification patterns

The UML class diagram for the specification pattern is shown below.

As you can see from the figure above, the spec mode mainly consists of six roles.

(1) Abstract Specification: Abstract definition of Specification.

(2) CompositeSpecification: generally designed as abstract class, the specification is operated with or without, and(), OR (), not() method is implemented, and the subclass is associated in the method, because the subclass is a fixed class, so the parent class can be associated.

(3) AndSpecification: The isSatisfiedBy() method was realized by conducting and operating the specification.

(4) OrSpecification (OrSpecification) : isSatisfiedBy() method is realized by performing or operating on the specification.

(5) NotSpecification: The isSatisfiedBy() method is realized by non-operation on the specification.

(6) BizSpecification: isSatisfiedBy() method is implemented to judge the business. A class is a judgment method and can be extended.

4 General specification mode writing

The following is a common way to write a specification pattern.


public class Client {

    public static void main(String[] args) {
        // The object to be analyzed
        List<Object> list = new ArrayList<Object>();
        Define two business specifications
        ISpecification spec1 = new BizSpecification("a");
        ISpecification spec2 = new BizSpecification("b");
        // Specification call
        for (Object o : list) {
            if(spec1.and(spec2).isSatisfiedBy(o)){  // if o satisfies spec1 && spec2System.out.println(o); }}}// Abstract specification
    interface ISpecification {
        // Whether the candidate meets the criteria
        boolean isSatisfiedBy (Object candidate) ;
        / / the and operation
        ISpecification and (ISpecification spec);
        / / the or operation
        ISpecification or (ISpecification spec);
        / / not operation
        ISpecification not (a);
    }

    // Combination specification
    static abstract class CompositeSpecification implements ISpecification {
        // Whether the condition is met is implemented by the subclass
        public abstract boolean isSatisfiedBy (Object candidate) ;
        / / the and operation
        public ISpecification and (ISpecification spec) {
            return new AndSpecification(this, spec);
        }
        / / the or operation
        public ISpecification or(ISpecification spec) {
            return new OrSpecification(this, spec);
        }
        / / not operation
        public ISpecification not(a) {
            return new NotSpecification(this); }}// With specifications
    static class AndSpecification extends CompositeSpecification {
        // Pass two specifications for and operation
        private ISpecification left;
        private ISpecification right;

        public AndSpecification(ISpecification left, ISpecification right) {
            this.left = left;
            this.right = right;
        }
        
        // Perform and
        public boolean isSatisfiedBy(Object candidate) {
            returnleft.isSatisfiedBy(candidate) && right.isSatisfiedBy(candidate); }}static class OrSpecification extends CompositeSpecification {
        // Pass two specifications for or operation
        private ISpecification left;
        private ISpecification right;

        public OrSpecification(ISpecification left, ISpecification right) {
            this.left= left;
            this.right = right;
        }

        // Perform the or operation
        public boolean isSatisfiedBy(Object candidate) {
            returnleft.isSatisfiedBy(candidate) || right.isSatisfiedBy(candidate); }}static class NotSpecification extends CompositeSpecification {
        // Pass two specifications for non-operation
        private ISpecification spec;

        public NotSpecification(ISpecification spec) {
            this.spec = spec;
        }

        // Perform the not operation
        public boolean isSatisfiedBy(Object candidate) {
            return !spec.isSatisfiedBy(candidate);
        }
    }

    // Business specification
    static class BizSpecification extends CompositeSpecification {
        // Base objects, such as names, can also be of type int
        private String obj;
        public BizSpecification(String obj) {
            this.obj = obj;
        }
        // Determine whether the requirements are met
        public boolean isSatisfiedBy(Object candidate){
            // Determine compliance based on the baseline object
            return true; }}}Copy the code

5. Advantages of specification mode

The specification pattern implements object filtering very cleverly, and is suitable for filtering and look-ups among multiple objects, or in cases where business rules do not fit into any existing entity or value object, and rule variations and combinations obscure the underlying meaning of the object.

6 Disadvantages of the specification pattern

A serious problem with the specification pattern is that the parent class depends on the child class, which only exists in scenarios where it is very clear that it will not change, it is not extensible, it is a fixed and immutable structure. In general, it should be avoided in object-oriented design.

Tom play architecture: 30 real cases of design patterns (attached source code), the challenge of annual salary 60W is not a dream

This article is “Tom play structure” original, reproduced please indicate the source. Technology is to share, I share my happiness! If this article is helpful to you, welcome to follow and like; If you have any suggestions can also leave a comment or private letter, your support is my motivation to adhere to the creation. Pay attention to “Tom bomb architecture” for more technical dry goods!