Как я могу избежать геттеров и избежать жесткого кодирования интерфейса? - PullRequest
3 голосов
/ 11 апреля 2011

Я хочу напечатать описание воина на консоли, которое будет включать в себя силу воина и оружие воина в виде This <description> warrior uses a <weapon> Например: This strong warrior uses a butter knife.

Редактировать для ясности: Я хочу сделать это, не запрашивая объекты для данных, используя методы получения или любой другой метод (например, toString), который показывает внутреннюю реализацию объекта.Я также хочу сделать это без жесткого кодирования моего текущего пользовательского интерфейса (консоли) в самих объектах.

public class Warrior
{
  private String description;
  private Weapon weapon;

  public Room(String description, Weapon weapon)
  {
    this.description = description;
    this.weapon = weapon
  }
}

public class Weapon
{
  private String name;

  public Weapon(String name)
  {
    this.name = name;
  }
}

Избегание получателей

Я могу избежать получателей путем жесткого кодирования пользовательского интерфейса:

//Warrior class
public void display() 
{
  String.out.println("This " + description + " warrior uses a ");
  weapon.display();
}

//Weapon class
public void display() 
{
  String.out.print(name);
}

Избегание жестко закодированного пользовательского интерфейса

Я могу избежать жестко закодированного пользовательского интерфейса, используя геттеры:

//Warrior class
public String getDescription() 
{
  return "This " + description + " warrior uses a " + weapon.getName();
}

//Weapon class
public String getName() 
{
  return name;
}

Можно ли избежать того и другого?Как я могу сделать это в приведенном выше примере?

Примечание. В ответ на некоторые первоначальные ответы метод получения не является методом, который следует соглашению об именах getSomeFieldName.Поэтому переименование getSomeFieldName в aMethodThatIsNotPrefixedByGet не является решением.Метод получения - это метод, который передает личные данные из объекта в область, которая его вызвала.

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

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

Ответы [ 6 ]

3 голосов
/ 11 апреля 2011

Да, перейдите на i18n ,

messages.properties
displayMessage = This {0} warrior uses a {1}

messages.properties_en_US
displayMessage = This {0} warrior uses a {1}

и

public static String getString(String key, Object... params  ) {
        try {
            return MessageFormat.format(RESOURCE_BUNDLE.getString(key), params);
        } catch (MissingResourceException e) {
            return '!' + key + '!';
        }
}
1 голос
/ 01 июля 2011
public Interface IWarriorView {
  public void display(String description, Weapon weapon);
}

public Interface IWeaponView {
  public void display(String name);
}

public class WeaponViewImpl {
  public void display(String name) {
    System.out.println(name);
  }
}

public class WarriorViewImpl {
  public void display(String description, Weapon weapon) {
    System.out.println("This " + description + " warrior uses a ");
    weapon.display(new WeaponImpl());
  }
}

// Warrior class
public String display(IWarriorView view) {
  view.display(description, weapon);
}

// Weapon class
public String display(IWeaponView view) {
  view.display(name);
}
1 голос
/ 11 апреля 2011

В этом случае метод получения мне кажется хорошей практикой, поскольку он позволяет вам отделить ваши данные (классы Воина и Оружия) от вашего пользовательского интерфейса (который вызывает методы получения и создает строки описания, виджеты, HTML-код и т. Д.).,Однако я бы не позволил получателю воина создать строку, он просто вернул бы описание воина, а класс пользовательского интерфейса создал бы строку (что предложенный вами метод Warrior.getDescription() делает в вашем примере).

1 голос
/ 11 апреля 2011

Я бы переопределил метод toString () как в Воине, так и в Оружии, так как этот метод естественным образом возвращает строковое представление объекта. Затем я создал бы класс, предназначенный для создания описаний, например DescriptionMaker, и создал бы в нем метод:

String createDescription(Warrior warrior, Weapon weapon)
{
    return "This " + warrior + " uses a " + weapon;
}

Возвращаемое значение этого метода может быть выведено на консоль. Кроме того, интернализация может применяться в классе DescriptionMaker.

1 голос
/ 11 апреля 2011

Вы можете переопределить toString в своем классе Воин, чтобы достичь этого.

public String toString() {


return "This " + this.description + " warrior uses a " + weapon.toString();

}

переопределить toString inWeapon, чтобы вернуть имя;

как

public String toString() {

    return this.name;

    }

и выможно напрямую печатать как

System.out.println(warrior);
0 голосов
/ 11 апреля 2011

Как насчет объединения обоих:

//Warrior class
public String display() 
{
  return "This " + description + " warrior uses a "+weapon.display();;

}

//Weapon class
public String display() 
{
  return name;
}
...