如何避免许多小类的代码重复?

时间:2009-03-17 17:47:03

标签: java oop casting

我有不同的类EnglishSpanishFrench等等:

Class English{
    String name = "English";
    String alias = "ENG";
}

Class French{
    String name = "French";
    String alias = "Fre";
}

与其他语言类似。

还有一个名为Language的课程:

Class Language{
    String name = "";
    String alias = "";
}

根据我的要求,我想将英语/法语/西班牙语投入我的语言课程。

Class ABC{

    main(){
        Language lan = new Language();
        Object obj = getObject(1);
        if(obj instanceof English){
            lan.name = ((English)obj).name;
            lan.aliasName = ((English)obj).aliasName;
        }
    }

}

如果我有10种语言,是否需要为10种不同的语言编写相同的代码? 在这种情况下,我如何制作单个方法并将这些参数作为参数传递? 像这样:

setVariablesForLanguage(String className, Object obj)

这里我只显示了2个变量,但我的类将包含100多个变量.. 我的实际需求是我想从其中一种语言中设置我的语言变量..

5 个答案:

答案 0 :(得分:15)

如果您正在制作几个持有常量值的小类,则不应该将它们作为类。我建议将它们作为语言的常量实例:

public static final Language ENGLISH = new Language("English", "Eng");
public static final Language FRENCH  = new Language("French",  "Fre");

并为Language提供一个匹配的构造函数。 (实际上,这看起来更像enum,但我不会立刻向你倾倒太多。)

然后在你的主要代码中,不要检查它是否是英语,法语等的实例。只需检查它是否是语言,然后调用

Language lan = new Language();
Object obj = getObject(1);
if(obj instanceof Language){
    lan.name = ((Language)obj).name;
    lan.aliasName = ((Language)obj).aliasName;
}

答案 1 :(得分:3)

使用声明Name和Alias属性的接口或抽象类。实现接口或从每个类的抽象类派生。

这是一个普遍的原则,适用于“很多看起来非常相似的课程”的常见问题 - 但这里到底发生了什么?为什么你会有多个英语实例?这里的真实状态是什么?

实际想要某种smart enum吗?

答案 2 :(得分:2)

  

如果我有10种语言,是否需要为10种不同的语言编写相同的代码?

不,实际上你可能根本不需要这些课程。

如果它们具有相同的属性,并且唯一使它们不同的是这些属性的值,则可以使用单个类(语言)并为每种语言使用不同的值。

当你说alais时,BTW所以你的意思是别名吗?

你可以这样:

public class Language  {

    String name;
    String alias;

    public Language( String aName, String anAlias ) { 
        this.name = aName;
        this.alias = anAlias;
    }
}

并相应地设置值。

如果你改变了“getObject()”的签名,那么它返回对象,它返回语言本身,然后你可以改变你的代码:

Language lan = new Language();

Object obj = getObject(1);

if(obj instanceof English){

    lan.name = ((English)obj).name;

    lan.aliasName = ((English)obj).alias;
}

对此:

Language lang  = getObject(1);

就是这样。在getObject内,你可以这样定义:

public Language getObject( int id ) { 
     switch( id ) { 
          case 0:  return new Language("English", "ENG");
          case 1:  return new Language("French", "FRE");
          case 2:  return new Language("Spanish", "ESP");
          case 3:  return new Language("German", "GER");
          case 4:  return new Language("Portuguese", "POR");
          ....
          etc. 
      }
}

您可能已经意识到,当行为 不同时,制作子类或不同的类是有意义的。当行为相同时,更改的唯一内容是数据,那么参数化类就足够了。

最后评论:

根据您的需要,您可以查看Locale类,并且可能会阅读此article以了解Java对于这种情况有什么作用。我不知道你的代码是否需要它,或者不需要它,这可能会有所帮助。

答案 3 :(得分:1)

这不是一个完整的问题解决方案(它甚至可能不是一个真正的解决方案),但我想指出一些我认为使用您提供的代码会更好的事情。

对于提供的代码,你最好写这样的东西:

abstract class Language
{
    private final String name;
    private final String alias;

    public Language(final String m, final String a)
    {
        name  = n;
        alias = a;
    }

    public String getName()
    {
        return (name);
    }

    public String getAlias()
    {
        return (alias);
    }
}

class English
    extends Language
{
    public English()
    {
        super("English", "ENG");
    }
}

class ABC
{
    public static void main(final String[] argv)
    {
        fnal Language lang;

        lang = getObject(1);
    }
}

一般来说:

  • 你应该尽量避免使用instanceof。
  • 如果你有相同类型的东西(比如英语,法语等等......你应该制作一个父类,并把常见的东西放在其中)。

答案 4 :(得分:0)

为什么不将英语,法语等全部作为语言的子类?

然后你的代码会更简单:


Class ABC{

main(){

 Language lan = getObject(1);

}

}

编辑:如上所述,语言也可以作为界面或抽象类做得更好。