Specification Pattern

Keywords: Java Design Pattern architecture

This article is excerpted from "design patterns should be learned this way"

1 definition of specification mode

Specification Pattern can be considered as an extension of composite pattern. Many times, some conditions in the program determine the business logic. These conditions can be extracted and combined in a certain relationship (and, or, non), so as to customize the business logic flexibly. In addition, in query, filtering and other applications, the whole implementation logic can be simplified by predefining multiple conditions and then using the combination of these conditions to process query or filtering, rather than using logical judgment statements.
Each condition here is a specification, and multiple specifications (conditions) form a combined specification in a logical relationship in series. Specification mode belongs to structural design mode.

2 application scenarios of specification mode

The specification mode is mainly applicable 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 business goal.

(2) Select objects or a subset of objects from the collection that meet specific business rules.

(3) Specify that certain business requirements must be met when creating new objects.

UML class diagram of 3 specification pattern

The UML class diagram of the specification pattern is shown in the figure below.

As can be seen from the above figure, the specification mode mainly includes six roles.

(1) Abstract Specification: an abstract definition of a Specification.

(2) Composite specification: it is generally designed as an abstract class, which performs and or non operations on the specification, implements and(), or(), not() methods, and associates subclasses in the methods. Because subclasses are fixed classes, parent classes can be associated.

(3) And specification: and operate the specification to realize the isSatisfiedBy() method.

(4) Or specification: or operate the specification to implement the isSatisfiedBy() method.

(5) NotSpecification: perform non operation on the specification to implement the isSatisfiedBy() method.

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

4 general writing method of specification mode

The following is a general description of the specification mode.

public class Client {

    public static void main(String[] args) {
        //Objects 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 meets spec1 & & spec2
                System.out.println(o);
            }
        }
    }

    //Abstract specification
    interface ISpecification {
        //Does the candidate meet the conditions
        boolean isSatisfiedBy (Object candidate) ;
        //and operation
        ISpecification and (ISpecification spec);
        //or operation
        ISpecification or (ISpecification spec);
        //not operation
        ISpecification not ();
    }

    //Combination specification
    static abstract class CompositeSpecification implements ISpecification {
        //Whether the conditions are met is implemented by subclasses
        public abstract boolean isSatisfiedBy (Object candidate) ;
        //and operation
        public ISpecification and (ISpecification spec) {
            return new AndSpecification(this, spec);
        }
        //or operation
        public ISpecification or(ISpecification spec) {
            return new OrSpecification(this, spec);
        }
        //not operation
        public ISpecification not() {
            return new NotSpecification(this);
        }
    }

    //And specifications
    static class AndSpecification extends CompositeSpecification {
        //Transfer two specifications for and operation
        private ISpecification left;
        private ISpecification right;

        public AndSpecification(ISpecification left, ISpecification right) {
            this.left = left;
            this.right = right;
        }
        
        //and operation
        public boolean isSatisfiedBy(Object candidate) {
            return left.isSatisfiedBy(candidate) && right.isSatisfiedBy(candidate);
        }
    }


    static class OrSpecification extends CompositeSpecification {
        //Transfer two specifications for or operation
        private ISpecification left;
        private ISpecification right;

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

        //or operation
        public boolean isSatisfiedBy(Object candidate) {
            return left.isSatisfiedBy(candidate) || right.isSatisfiedBy(candidate);
        }
    }

    static class NotSpecification extends CompositeSpecification {
        //Transfer 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 {
        //The reference object, such as name, can also be of type int
        private String obj;
        public BizSpecification(String obj) {
            this.obj = obj;
        }
        //Judge whether the requirements are met
        public boolean isSatisfiedBy(Object candidate){
            //Judge whether it meets the requirements according to the benchmark object
            return true;
        }
    }
}

5 advantages of specification mode

The specification pattern cleverly implements the object filtering function, which is suitable for filtering and searching in multiple objects, or business rules are not suitable for placing in any existing entity or value object, and the change and combination of rules will mask the basic meaning of the object.

6 disadvantages of specification mode

A very serious problem in the specification pattern is that the parent class depends on the child class. This scenario exists only in the scenario that is very clear that it will not change. It does not have scalability and is a fixed and unchangeable structure. Generally, it should be avoided in object-oriented design.

Focus on WeChat's official account of Tom architecture and reply to the "design pattern" to get the complete source code.

[recommendation] Tom bomb architecture: 30 real cases of design patterns (with source code attached). Challenging the annual salary of 60W is not a dream

This article is the original of "Tom bomb architecture". Please indicate the source for reprint. Technology lies in sharing, I share my happiness!
If this article is helpful to you, you are welcome to pay attention and praise; If you have any suggestions, you can also leave comments or private letters. Your support is the driving force for me to adhere to my creation. Focus on WeChat official account Tom structure, get more dry cargo!

Posted by supernova on Thu, 25 Nov 2021 15:37:49 -0800