Wzorzec projektowy interpreter
Stronę tą wyświetlono już: 2517 razy
Opis wzorca projektowego interpreter
Wzorzec projektowy interpreter należy do czynnościowych wzorców projektowych. Jego zadaniem jest podział zadań interpretacji składni prostych wyrażeń arytmetycznych. Główna klasa parsuje dane przygotowując je dla podklas np. w przypadku interpretacji wyrażenia matematycznego: 5+2.5*3+5/5-5 główna instancja interpretera sparsuje to wyrażenie do postaci listy:
- 5
- +
- 2.5
- *
- 3
- +
- 5
- /
- 5
- -
- 5
Następnie poszczególne instancje klas wykonają działania:
- mnożenia - względem operatora *
- dzielenia - względem operatora /
- dodawania - względem operatora +
- odejmowania - względem operatora -
Przykładowy diagram UML wzorca projektowego interpreter
Użytkownik (program) tworzy instancję klasy Interpreter, która agreguje obiekty klas:
- Multiply - odpowiedzialnej za realizację działania mnożenia;
- Divide - odpowiedzialnej za realizację działania dzielenia;
- Add - odpowiedzialnej za realizację działania dodawania;
- Subtract - odpowiedzialnej za realizację działania odejmowania
Przykład implementacji wzorca projektowego interpreter w C++
- #include <iostream>
- #include <string>
- #include <vector>
- const std::string operators("*/+-");
- class Multiply;
- class Divided;
- class Add;
- class Subtract;
- class Interpreter{
- protected:
- std::vector<std::string> equation;
- std::vector<std::string>::iterator findOperator(std::vector<std::string> &equation, std::string operatorName){
- for(std::vector<std::string>::iterator i = equation.begin(); i < equation.end(); i++){
- if((*i) == operatorName)
- return i;
- }
- return equation.end();
- }
- void parseString(std::string equation){
- std::string::size_type index = equation.find_first_of(operators);
- while(index != std::string::npos){
- if(index != 0){
- this->equation.push_back(equation.substr(0, index));
- equation.erase(0, index);
- }
- this->equation.push_back(equation.substr(0, 1));
- equation.erase(0, 1);
- index = equation.find_first_of(operators);
- }
- if(!equation.empty()){
- this->equation.push_back(equation);
- }
- }
- virtual void interprete(std::vector<std::string> & equation){}
- Interpreter* multiplyOperation;
- Interpreter* divideOperation;
- Interpreter* addOperation;
- Interpreter* subtractOperation;
- public:
- Interpreter(std::string equation);
- Interpreter(){
- multiplyOperation = divideOperation = addOperation = subtractOperation = NULL;
- }
- virtual ~Interpreter(){
- if(multiplyOperation){
- delete multiplyOperation;
- multiplyOperation = NULL;
- }
- if(divideOperation){
- delete divideOperation;
- divideOperation = NULL;
- }
- if(addOperation){
- delete addOperation;
- addOperation = NULL;
- }
- if(subtractOperation){
- delete subtractOperation;
- subtractOperation = NULL;
- }
- }
- };
- class Multiply : public Interpreter{
- protected:
- std::vector<std::string>::iterator findMultiplyOperator(std::vector<std::string> &equation){
- return findOperator(equation, "*");
- }
- std::string calculate(std::string left, std::string right){
- double l = atof(left.c_str());
- double r = atof(right.c_str());
- char value[100];
- gcvt(l * r, 10, value);
- return std::string(value);
- }
- virtual void interprete(std::vector<std::string> &equation){
- std::vector<std::string>::iterator operatorPointer = findMultiplyOperator(equation);
- while(operatorPointer != equation.end()){
- int pos = (int)(operatorPointer - equation.begin());
- std::string value = calculate(*(operatorPointer - 1), *(operatorPointer + 1));
- equation.insert(operatorPointer - 1, value);
- equation.erase(equation.begin() + pos, equation.begin() + pos + 3);
- operatorPointer = findMultiplyOperator(equation);
- }
- }
- };
- class Divide : public Interpreter{
- protected:
- std::vector<std::string>::iterator findDivideOperator(std::vector<std::string> &equation){
- return findOperator(equation, "/");
- }
- std::string calculate(std::string left, std::string right){
- double l = atof(left.c_str());
- double r = atof(right.c_str());
- char value[100];
- gcvt(l / r, 10, value);
- return std::string(value);
- }
- virtual void interprete(std::vector<std::string> &equation){
- std::vector<std::string>::iterator operatorPointer = findDivideOperator(equation);
- while(operatorPointer != equation.end()){
- int pos = (int)(operatorPointer - equation.begin());
- std::string value = calculate(*(operatorPointer - 1), *(operatorPointer + 1));
- equation.insert(operatorPointer - 1, value);
- equation.erase(equation.begin() + pos, equation.begin() + pos + 3);
- operatorPointer = findDivideOperator(equation);
- }
- }
- };
- class Add : public Interpreter{
- protected:
- std::vector<std::string>::iterator findAddOperator(std::vector<std::string> &equation){
- return findOperator(equation, "+");
- }
- std::string calculate(std::string left, std::string right){
- double l = atof(left.c_str());
- double r = atof(right.c_str());
- char value[100];
- gcvt(l + r, 10, value);
- return std::string(value);
- }
- virtual void interprete(std::vector<std::string> &equation){
- std::vector<std::string>::iterator operatorPointer = findAddOperator(equation);
- while(operatorPointer != equation.end()){
- int pos = (int)(operatorPointer - equation.begin());
- std::string value = calculate(*(operatorPointer - 1), *(operatorPointer + 1));
- equation.insert(operatorPointer - 1, value);
- equation.erase(equation.begin() + pos, equation.begin() + pos + 3);
- operatorPointer = findAddOperator(equation);
- }
- }
- };
- class Subtract : public Interpreter{
- protected:
- std::vector<std::string>::iterator findSubtractOperator(std::vector<std::string> &equation){
- return findOperator(equation, "-");
- }
- std::string calculate(std::string left, std::string right){
- double l = atof(left.c_str());
- double r = atof(right.c_str());
- char value[100];
- gcvt(l - r, 10, value);
- return std::string(value);
- }
- virtual void interprete(std::vector<std::string> &equation){
- std::vector<std::string>::iterator operatorPointer = findSubtractOperator(equation);
- while(operatorPointer != equation.end()){
- int pos = (int)(operatorPointer - equation.begin());
- std::string value = calculate(*(operatorPointer - 1), *(operatorPointer + 1));
- equation.insert(operatorPointer - 1, value);
- equation.erase(equation.begin() + pos, equation.begin() + pos + 3);
- operatorPointer = findSubtractOperator(equation);
- }
- }
- };
- int main(){
- Interpreter interpreter("5+2.5*3+5/5-5");
- std::cin.get();
- return 0;
- }
- Interpreter::Interpreter(std::string equation){
- std::cout << "Parse equation: " << equation << std::endl;
- parseString(equation);
- for(std::vector<std::string>::iterator i = this->equation.begin(); i < this->equation.end(); i++){
- std::cout << *i << std::endl;
- }
- multiplyOperation = new Multiply;
- multiplyOperation->interprete(this->equation);
- std::cout << "After multiply:" << std::endl;
- for(std::vector<std::string>::iterator i = this->equation.begin(); i < this->equation.end(); i++){
- std::cout << *i << std::endl;
- }
- divideOperation = new Divide;
- divideOperation->interprete(this->equation);
- std::cout << "After divided:" << std::endl;
- for(std::vector<std::string>::iterator i = this->equation.begin(); i < this->equation.end(); i++){
- std::cout << *i << std::endl;
- }
- divideOperation = new Add;
- divideOperation->interprete(this->equation);
- std::cout << "After added:" << std::endl;
- for(std::vector<std::string>::iterator i = this->equation.begin(); i < this->equation.end(); i++){
- std::cout << *i << std::endl;
- }
- subtractOperation = new Subtract;
- subtractOperation->interprete(this->equation);
- std::cout << "Calculated:" << std::endl;
- for(std::vector<std::string>::iterator i = this->equation.begin(); i < this->equation.end(); i++){
- std::cout << *i << std::endl;
- }
- }
Wynik działania powyższego kodu:
Parse equation: 5+2.5*3+5/5-5 5 + 2.5 * 3 + 5 / 5 - 5 After multiply: 5 + 7.5 + 5 / 5 - 5 After divided: 5 + 7.5 + 1. - 5 After added: 13.5 - 5 Calculated: 8.5

Tytuł:
React 17. Wzorce projektowe i najlepsze praktyki. Projektowanie i rozwijanie nowoczesnych aplikacji internetowych. Wydanie III
Autor:
Carlos Santana Roldán

Tytuł:
Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II
Autor:
Eric Freeman, Elisabeth Robson

Tytuł:
Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku
Autor:
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Tytuł:
Projektowanie interfejsów., Sprawdzone wzorce projektowe. Wydanie III
Autor:
Jenifer Tidwell, Charles Brewer, Aynne Valencia-Brooks

Tytuł:
Kubernetes. Wzorce projektowe. Komponenty wielokrotnego użycia do projektowania natywnych aplikacji chmurowych
Autor:
Bilgin Ibryam, Roland Huß

Tytuł:
Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Programowanie zorientowane obiektowo. Wzorce projektowe. Wydanie II
Autor:
Alan Shalloway, James R. Trott

Tytuł:
Java EE 8. Wzorce projektowe i najlepsze praktyki
Autor:
Rhuan Rocha, Joao Purificacao

Tytuł:
Systemy reaktywne. Wzorce projektowe i ich stosowanie
Autor:
Roland Kuhn Dr., Brian Hanafee, Jamie Allen