Click here to Skip to main content
Click here to Skip to main content

Design a Business Expression with the Interpreter Pattern

, 25 Jan 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
In this article, I will use Interpreter Pattern to design a business expression

Introduction

In enterprise applications, we sometimes need to provide users a flexible way to configure the application. In this article, I will demonstrate how to design a general purpose business expression with the Interpreter pattern for this requirement.

Business Expression

An expression is a finite combination of symbols that is well-formed according to rules that depend on the context. The business expression we want to provide to the user has the following grammar definition:

Business Expression ::= ‘{‘ Operator ‘@’ Operand { ‘;’ … } ‘}’
Operator ::= ‘ADD’ | ‘SUB’ | ‘MUL’ | ‘DIV’
Operand ::= Business Expression | Data
Data ::= ‘1’ | ‘2’ …

There are several business expression examples:

{ADD@1;2}

This business expression represents we want to get the result of 1 + 2.

{SUB@3;2}

This business expression represents we want to get the result of 3 – 2.

{MUL@2;5}

This business expression represents we want to get the result of 2 * 5.

{DIV@4;2}

This business expression represents we want to get the result of 4 / 2.

{MUL@2;{DIV@{ADD:5;3};{SUB@5;1}}}

This is a more complicated business expression. It equals 2 * ((5 + 3) / (5 – 1)).

Applying the Interpreter Pattern

The definition of the Interpreter pattern is this: given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

Interpreter Pattern

From the definition of the Interpreter pattern, we can see a business expression is a perfect candidate to apply the Interpreter pattern. We can define each part of the business expression as a business expression class that is used to represent the business expression grammar and put them together as a business expression hierarchy.

Business Expression

In the business expression hierarchy, we have a BusinessExpression class similar to the AbstractExpression in the pattern, have BusinessDataExpression similar to the TerminalExpression in the pattern, and have BusinessCompositeExpression together with all its subclasses similar to the NonterminalExpression in the pattern. Therefore, client routing can use the business expression to evaluate a given business expression string.

Where is the Context class?

The Interpreter pattern diagram has a context class. It’s not in my business expression diagram. The reason that I didn’t include a context class is because the purpose of the context class in the Interpreter pattern is to contain the input string and the result. Therefore, it’s not a must have class. Without the context class, I can just pass the input string into a business expression with an input parameter and get the result back with a return value.

How to use a business expression

To use a business expression, we need to follow these steps:

  1. Translate the business expression string into a business expression object tree.
  2. Evaluate the business expression object tree to get the result.
Translating into a business expression object tree

The business expression is given as a string, such as {ADD@1;2}. The way to translate this string into a business expression object tree is by traversing through each character in the string and translating any recognized term into the corresponding business expression object. The Parse static method on the BusinessExpression class is designed for translating a business expression string into a business expression object tree. It uses a process stack internally to store the intermediate results during the process. An intermediate result is represented with the ProcessAtom class.

Process Atom

There are three types of ProcessAtom: Raw Data, Incomplete Business Expression, and Completed Business Expression.

Raw Data: It’s a single character in a business expression string. When the processor can’t determine how to convert a single character into a business expression, it will just store the character as raw data and wait for more information.

Incomplete Business Expression: It’s a business expression that has not been processed completely. A business expression starts with the symbol ‘{‘ and ends with ‘}’. Before the ending symbol is reached, the processor will just store an incomplete business expression into the process stack and wait for the ending symbol.

Completed Business Expression: It’s a business expression that has been fully processed. A completed business expression is generated by the processor after processing both ‘{‘ and ‘}’.

Evaluating business expression

After we have the business expression object tree, we can call the evaluate method of the root business expression object to get the result of business expression string. Each business expression object knows how to evaluate itself or get the result from containing business expression. The root business expression object consolidates the result together and returns back to the client.

Related Design Patterns

The business expression is a perfect candidate to apply the Interpreter pattern, however, the Interpreter pattern can’t fulfill the requirement by itself, there are other patterns employed.

Composite Pattern

The business expression object tree is built with the Composite pattern, so we can have nested business expressions in a business expression. By doing this, a more complicated business expression can be defined.

Factory Pattern

The Parse method has a fixed algorithm on how the business expression string gets parsed into a business expression object tree, but we might want to add a new business expression sometimes to support a new operation. According to the single responsibility principle, we should not let the parser method directly create the business expression object. Instead, we want the business expression object creation be done in a factory class. Therefore, we can just add a new business class and change BusinessExpressionFactory to return the new business expression object into the parser.

public class BusinessExpressionFactory
{
    public BusinessExpressionFactory()
    {
    }

    public BusinessExpression CreateBusinessExpression(string type)
    {
        BusinessExpression businessExpression = null;

        switch (type.ToLower())
        {
            case "add":
                businessExpression = new BusinessAdditionExpression();
                break;
            case "sub":
                businessExpression = new BusinessSubstractionExpression();
                break;
            case "mul":
                businessExpression = new BusinessMultiplicationExpression();
                break;
            case "div":
                businessExpression = new BusinessDivisionExpression();
                break;
        }

        return businessExpression;
    }
}

Summary

A business expression is a typical requirement for enterprise applications. By utilizing the Interpreter pattern, we can provide an elegant solution to fulfill it.

Using the Code

The code is developed in Visual Studio 2010. You can add your own business expression class into it to see the clarity and extensibility in the example from using Design Patterns.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Henry He
Software Developer (Senior)
United States United States
Senior Software Developer from New Jersey, USA

Have 15+ years experience on enterprise application development with various technologies.

Comments and Discussions

 
GeneralCool PinprofessionalRolando CC7-Nov-13 7:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 25 Jan 2012
Article Copyright 2012 by Henry He
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid