【问题标题】:Java Program Organization: How can I get rid of this massive case statement?Java Program Organization:我怎样才能摆脱这个庞大的案例陈述?
【发布时间】:2010-07-10 20:21:21
【问题描述】:

我正在创建一个程序来填充给定的语法。现在我正在模拟这样的“词类”:

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";
    }
}

【问题讨论】:

    标签: java architecture oop switch-statement


    【解决方案1】:

    我只想创建一个字典或从缩写到完整描述的映射。然后getKind 会在映射中查找它的输入并返回结果,如果输入没有映射到任何东西,other 会返回。

    【讨论】:

    • 我认为这是个好主意,但是,它并没有说明有些词有子类别。即:名词可以是单数也可以是复数。
    • @sixtyfootersdude 您的原始解决方案也没有。 getKind(String s) 函数,s 只是与每个常量进行比较。您是否打算在将代码传递给getKind() 之前发布代码以检索s
    • 为了支持多个子类别,您可以只使用描述符列表(或字符串:“Npo”将描述复数主格名词)。或者您可以创建一堆子类别(如大小写、性别、时态、人称、变格等)并将它们分配给每个单词的一部分 List<Subcategory>
    【解决方案2】:

    你可以用枚举类型做一些事情。

    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()
    

    此解决方案假定每个单词只有一个词性。为了允许修饰符,例如“第一人称”、“第三人称”、“复数”、“现在”、“渐进式”等,您可以简单地列举所有这些——这是一项乏味的工作,但只需要完成一次.或者,您可以调整 Decorator Pattern,它专门解决了动态向对象添加属性的需要。

    另一个建议是枚举修饰符:

    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。

    【讨论】:

    • 我认为这是个好主意,但是,它并没有说明有些词有子类别。即:名词可以是单数也可以是复数。
    • 您的原始解决方案也没有解决这个问题。我将添加一些注释,为您指明一些适当的方向。
    【解决方案3】:

    您能否使用带有代码(在您的情况下为s)作为键并将返回的字符串作为值的字典?

    【讨论】:

    • 最简单的解决方案,几乎总是最好的
    猜你喜欢
    • 2021-01-27
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2022-10-18
    • 2020-01-05
    相关资源
    最近更新 更多