Организация программ на Java: как мне избавиться от этого массивного описания случая? - PullRequest
3 голосов
/ 11 июля 2010

Я создаю программу, которая заполнит данную грамматику. Прямо сейчас я моделирую "виды слов", как это:

public class WordDescriptor {

    public static final String noun = "N";
    public static final String plural = "p";
    public static final String nounPhrase = "h";
    public static final String usuParticipleVerb = "V";
    public static final String transitiveVerb = "t";
    public static final String intransitiveVerb = "i";
    public static final String adjective = "A";
    public static final String adverb = "v";
    public static final String conjunction = "C";
    public static final String preposition = "P";
    public static final String interjection = "!";
    public static final String pronoun = "r";
    public static final String definiteArticle = "D";
    public static final String indefiniteArticle = "I";
    public static final String nominative = "o";
    public static final String defaultTag = "?";

    private String word; // where word is one of the constants defined above.  

    public String getWord(){
        return word;
    }

    public String setWord(){
        return word;
    }

    /** For debugging only.  
     * 
     * @param s
     * @return
     */
    protected static String getKind(String s){
        if(s.equals(noun)){
            return "noun";
        }else if(s.equals(plural)){
            return "plural";
        }else if(s.equals(nounPhrase)){
            return "nounPhrase";
        }else if(s.equals(usuParticipleVerb)){
            return "usuParticipleVerb";
        }else if(s.equals(transitiveVerb)){
            return "transitiveVerb";
        }else if(s.equals(intransitiveVerb)){
            return "intransitiveVerb";
        }else if(s.equals(adjective)){
            return "adjective";
        }else if(s.equals(adverb)){
            return "adverb";
        }else if(s.equals(conjunction)){
            return "conjunction";
        }else if(s.equals(preposition)){
            return "preposition";
        }else if(s.equals(interjection)){
            return "interjection";
        }else if(s.equals(pronoun)){
            return "pronoun";
        }else if(s.equals(definiteArticle)){
            return "definiteArticle";
        }else if(s.equals(indefiniteArticle)){
            return "indefiniteArticle";
        }else if(s.equals(nominative)){
            return "nominative";
        } else if(s.equals(defaultTag)){
            return "defaultTag";
        }else{
            return "other: "+s;
        }
    }

}

Это довольно уродливый код, который я могу себе представить. Я знаю, что могу сделать это немного лучше, используя case, однако это все еще чертовски уродливо. Вот мой вопрос:

Как я могу сделать это красиво? Я думал о создании:

  • класс WordDescriptor, с подклассами:
    • существительное класса с подклассами:
      • сингулярным
      • множественное число
    • глагол класса
    • наречие класса

Но я не уверен, что это тоже кажется отличной идеей. Как я могу это лучше?


Редактировать: Если бы я выбрал второй подход, я даже не уверен, как будут выглядеть классы. Вот пример:

public abstract class WordDescriptor {

   public String toString();

}

public class Noun extends WordDescriptor {

    public String toString(){
        return "Noun";
    }
}

public class Plural extends Noun{
    public String toString(){
        return "Plural";
    }
}

Ответы [ 3 ]

12 голосов
/ 11 июля 2010

Я бы просто создал словарь или карту от аббревиатуры до полного описания. Тогда getKind будет искать свой вход в отображении и будет возвращать результат, или other, если вход не будет сопоставлен ни с чем.

6 голосов
/ 11 июля 2010

Вы можете сделать что-то с перечислимым типом.

public enum SpeechPart
{
    NOUN ("noun"),
    PLURAL ("plural"),
    NOUNPHRASE ("noun phrase"),
    ADVERB ("adverb"),
    ADJECTIVE ("adjective"),
    CONJUNCTION ("conjunction"),
    VERB ("verb");

    private String english;

    SpeechPart(String inEnglish)
    {
        this.english = inEnglish;
    }

    public String toString() { return english; }
}

Теперь вы можете присвоить их переменной.

SpeechPart dog = SpeechPart.NOUN;
SpeechPart ran = SpeechPart.VERB;
SpeechPart quickly = SpeechPart.ADVERB;

И тогда вы можете увидеть, каковы их части речи:

System.out.println(dog.toString());
System.out.println(quickly);        // Implicit call to toString()

Это решение предполагает только одну часть речи на слово. Чтобы учесть такие модификаторы, как «от первого лица», «от третьего лица», «множественное число», «настоящее», «прогрессивный» и т. Д., Вы можете просто перечислить все из них - утомительная работа, но ее нужно выполнить только один раз , В качестве альтернативы, вы можете адаптировать Pattern Decorator , который конкретно учитывает необходимость динамического добавления атрибутов к объекту.

Еще одно предложение - перечислить модификаторы:

public enum SpeechModifier
{
    SINGULAR,
    PLURAL,
    FIRST_PERSON,
    SECOND_PERSON,
    THIRD_PERSON,
    PRESENT,
    PAST,
    PERFECT,
    PROGRESSIVE;
}

Затем создайте класс, который объединяет их вместе:

public class Word
{
    String word;
    SpeechPart part;
    EnumSet<SpeechModifier> modifiers;
}

Теперь вы можете смоделировать целое слово:

Word w1 = new Word();
w1.word = "bouncing";
w1.part = SpeechPart.VERB;
w1.modifiers = EnumSet<SpeechModifier>.of(SpeechModifier.PRESENT, SpeechModifier.PROGRESSIVE);

Это решение, однако, не предотвращает бессмысленные комбинации, такие как FIRST_PERSON NOUN PAST.

2 голосов
/ 11 июля 2010

Не могли бы вы использовать словарь с кодом (s в вашем случае) в качестве ключа и возвращаемой строкой в ​​качестве значения?

...