DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Data
  4. Behavioral Design Patterns: Interpreter

Behavioral Design Patterns: Interpreter

Want to learn more about implementing the Interpreter behavioral design pattern in Java? Check out this post to learn more.

Emmanouil Gkatziouras user avatar by
Emmanouil Gkatziouras
CORE ·
Oct. 24, 18 · Tutorial
Like (10)
Save
Tweet
Share
13.72K Views

Join the DZone community and get the full member experience.

Join For Free
Previously, we had a look at the chain of responsibility and the command pattern. They do tackle different problems; however, they both delegate an action to another component — the command patterns always delegate the action, and the chain of responsibility, if the action cannot be handled, will forward it to its successor.

We are going to switch context and check the interpreter pattern. The interpreter pattern specifies how to evaluate custom languages. The examples are limitless, for example, the spel language for Spring or even SQL.

We will keep things simple and create an interpreter for a simple query language only with select and where statements. This is not impossible in the real world, just think about dynamodb and how simple its expressions are — the possibilities are countless.

So, let’s start with our clause interface.

package com.gkatzioura.design.behavioural.interpreter;

public interface Clause{

}


I will implement the WhereClause.

package com.gkatzioura.design.behavioural.interpreter;


public class WhereClause implements Clause {

    /**
     * Add values related to the where clause functions and expressions
     */

    public WhereClause() {
    }

    /**
     * Add functions for expressions for equals not equals etc.
     */

}


And the SelectClause:

package com.gkatzioura.design.behavioural.interpreter;

import java.util.Optional;

public class SelectClause implements Clause {

    private Optional<WhereClause> optWhereClause = Optional.empty();

    public <T> T load(Class<T> valueType) {

        /**
         * Apply filter according to the where clause
         */
        if(optWhereClause.isPresent()) {

        }

        /**
         * Load data
         */

        /**
         * Serialize/Deserialize data based on the type
         * For example if you use jackson it will be:  new ObjectMapper().readValue("text",valueType);
         */


        return null;
    }

    public void setWhereClause(WhereClause whereClause) {
        this.optWhereClause = Optional.of(whereClause);
    }
}


The load function shall load our data based on the expression given.

Both clauses are linked together; however, the select clause can produce results even when ‘where’ statements have not been given whatsoever. In any case, when it comes to loading the data, the select clause will check and apply any filter statements that the where clause might have (if exists) and then return the data. Let’s move to the interpreter-specific parts.

We will create the expression interface.

package com.gkatzioura.design.behavioural.interpreter;

public interface Expression {

    Clause interpret(String context);

}


The interpretation of the text given will give us back a clause.

Next, we shall create the WhereExpression.

package com.gkatzioura.design.behavioural.interpreter;

public class WhereExpression implements Expression {

    @Override
    public WhereClause interpret(String context) {
        WhereClause whereClause = new WhereClause();
        /**
         * Parse the string and find any where statements ie. A=1 AND B!=2 and apply them.
         */

        return whereClause;
    }

}


And the SelectExpression.

package com.gkatzioura.design.behavioural.interpreter;

public class SelectExpression implements Expression {

    @Override
    public SelectClause interpret(String context) {
        SelectClause selectClause = new SelectClause();

        /**
         * Parse text and check for expressions like `SELECT * FROM ` or `SELECT A,B,C FROM` .
         */

        return selectClause;
    }

}


The last step would be theQueryExpression.

package com.gkatzioura.design.behavioural.interpreter;

public class QueryExpression implements Expression {

    @Override
    public SelectClause interpret(String context) {

        SelectClause selectClause = new SelectExpression().interpret(context);

        if(context.contains("WHERE")) {

            WhereClause whereClause = new WhereExpression().interpret(context);
            selectClause.setWhereClause(whereClause);
        }

        return selectClause;
    }

}


So, let’s put them all together. We shall interpret a query that fetches a list of integers.

package com.gkatzioura.design.behavioural.interpreter;

public class Interpreter {

    public static void main(String[] args) {
        String selectionString = "SELECT b FROM foo WHERE a=1";
        Integer[] values = new QueryExpression()
                .interpret(selectionString)
                .load(Integer[].class);
    }

}


You can find the source code on GitHub.

Design Interpreter pattern Query language Data (computing) Interface (computing) Command (computing) Database GitHub

Published at DZone with permission of Emmanouil Gkatziouras, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Do Not Forget About Testing!
  • Beginners’ Guide to Run a Linux Server Securely
  • Fraud Detection With Apache Kafka, KSQL, and Apache Flink
  • AIOps Being Powered by Robotic Data Automation

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: