2015-07-10 4 views
1

Я должен создать интерпретатор мини-команд (System.in) в Java для поддержки манипуляции графическим объектом с использованием соответствующих шаблонов GoF. Грамматика переводчика является простым языком EBNF так: поведение `Если и как использовать Composite pattern (GoF's)

<cmd>::=<create>|<remove>|<move>|<scale>|<list>|<group>|<ungroup>|<area>|<perimeter> 
<create>::= new <typeconstr> <pos> 
<remove>::= del <objID> 
<move>::= mv <objID> <pos> | mvoff <objID> <pos> 
<scale>::= scale <objID> <posfloat> 
<list>::= ls <objID>| ls <type> | ls all | ls groups 
<group>::= grp <listID> 
<ungroup>::= ungrp <objID> 
<area>::= area <objID>| area <type> | area all 
<perimeter>::= perimeter <objID>| perimeter <type> | perimeter all 
<pos>::=(<posfloat> , <posfloat>) 
<typeconstr>::= circle (<posfloat>) | rectangle <pos> | img (<path>) 
<type>::= circle | rectangle | img 
<listID>::= <objID> { , <objID> } 

команд управляется шаблон Command, и это нормально.

Я думал, что проще всего использовать шаблон Composite для структуры общей команды, но я счел это трудной задачей. Есть рекомендации?

Является ли только шаблон интерпретатора хорошим выбором для этого? Или сочетание обоих?

Как только у меня есть структура Composite, я подумал использовать Builder с ним (возможно, рекурсивный Builder), чтобы создать команду.

спасибо.

ответ

0

Композит - отличный образец для представления древовидных структур, но я не думаю, что это хорошо подходит для того, что вы здесь делаете. Ваши команды не глубоко вложены, и нет рекурсивной вложенности, поэтому вы, вероятно, не получите большую пользу от этой структуры.

Ваши команды структурированы так, что первый токен определяет действие, и для разбора остальной строки существуют правила, специфичные для команды. Шаблон команды выглядит идеально, и я предложил бы использовать шаблон фабрики для инкапсуляции конкретных реализаций:

public class MyCommand{ 
    public static MyCommand getInstance(String str){ 
     String commandType = // get first token 
     String args = // remainder of string 

     switch (commandType){ 
      case "new": 
       return buildCreateCommand(args); 
      // ... other cases 
     } 
    } 

    private MyCreateCommand buildCreateCommand(String args){ 
     // Construct create command from args 
    } 
} 

class MyCreateCommand extends MyCommand{ 
    // Create command things 
} 
+0

спасибо, я постараюсь – Paolo89

+0

HI, я не понимаю, преимущество вашего заводского решения. По сравнению с шаблоном фабричного метода GoF у вас нет заводской иерархии. Каковы преимущества? – Paolo89

+0

Большим преимуществом шаблона Factory является то, что метод может выбрать, какой подкласс должен быть создан, а точный тип не отображается вызывающему. В этом случае 'getInstance' проверяет командную строку и решает на основе первого токена, какой тип команды он есть. Это означает, что вы можете добавлять новые команды без изменения клиента, может изменять, как каждая команда идентифицируется только в одном месте, и вы можете изменять синтаксис каждой команды независимо. – hugh

 Смежные вопросы

  • Нет связанных вопросов^_^