2009-03-17 2 views
3

У меня есть различные классы, называемые English, Spanish, French и т.д .:Как избежать дублирования кода со многими небольшими классами?

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) 

Здесь я показал только две переменные, но мой класс будет содержать более 100 переменных .. Мой фактический rewquirment, я хочу, чтобы установить мои языковые переменные из одного из этих языков ..

ответ

3

Используйте интерфейс или абстрактный класс, который объявляет свойства Name и Alias. Внедрить интерфейс или получить от абстрактного класса для каждого из ваших классов.

Это общий принцип, который работает для общей проблемы «много классов, которые выглядят очень похожими» - но что здесь происходит? Почему у вас есть несколько экземпляров английского языка? Какое здесь настоящее состояние?

У вас есть на самом деле Хотите что-то вроде smart enum?

0

Почему бы не сделать английский, французский и т. Д. Все подклассы языка?

Тогда ваш код будет проще:


Class ABC{ 

main(){ 

Language lan = getObject(1); 

} 

} 

Edit: Как уже говорилось выше, язык также может сделать лучше, как интерфейс или абстрактный класс.

+0

Как используется выше, поведение понятия «язык» сопоставляется с одним классом. Каждый язык будет экземпляром этого класса. Определение подкласса для каждого языка вовсе не помогло бы избежать дублирования кода! – xtofl

15

Если вы делаете несколько небольших классов, каждый из которых имеет постоянные значения, вы не должны создавать классы. Я предлагаю сделать их постоянными экземплярами Язык:

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

И дать языку конструктор для соответствия. (На самом деле, это больше похоже на enum, но я не буду сбрасывать слишком много на вас сразу.)

Тогда в вашем основном коде не проверяйте, является ли это экземпляром английского, французского и т. Д. Просто убедитесь, что это язык, а затем вызвать

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

+1, только то, что я хотел опубликовать (может быть, помимо isinstance-stuff, поскольку мне это не нравится;)) – Tetha

+1

Принцип здесь - «Подкласс для изменения поведения, а не данных». Поскольку поведение не меняется, вам не нужно больше одного класса. –

+1

На самом деле вы, вероятно, хотите перечисления, но функциональность была бы почти такой же, как и этот ответ. –

2

Если у меня есть 10 языков, мне нужно, чтобы написать тот же код на 10 разных языках?

Нет, на самом деле, возможно, вам даже не нужны классы вообще.

Если у них одни и те же свойства, и единственное, что делает их разными, это значения этих свойств, вы можете иметь один класс (язык) и использовать разные значения для каждого языка.

Кстати, вы имеете в виду псевдоним, когда говорите alais?

Вы могли бы это так:

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 есть для такого рода ситуаций. Я не знаю, нужен ли ваш код или нет, но может быть полезно.

+0

Почему бы вам просто не вернуть новый язык (((Language) obj) .name, ((Language) obj).псевдоним) только один раз. Что происходит с записью такого блока блокировки коммутатора и дублирования кода «n» раз? –

+0

@Livepool: Я даже не знаю, что внутри метода getObject, скорее всего, объект создается внутри. Зачем мне создавать Object, пока мы можем создать экземпляр самого языка. Только «Чинни» может сказать. – OscarRyz

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 как можно больше.
  • Если у вас есть вещи того же типа (например, английский, французский и т. Д.), Вы должны создать родительский класс и поместить в него общие вещи).
+1

- Когда единственное, что меняется, это данные, просто параметризуйте, не подклассы. – OscarRyz

+0

Я согласен - я просто фиксировал представленный код ... – TofuBeer