3

我想在控制台上打印一个战士的描述,其中包括战士的力量和战士的武器,格式This <description> warrior uses a <weapon>为例如:This strong warrior uses a butter knife.

为清楚起见进行编辑:我想这样做而不是通过使用 getter 或任何其他方法(如 toString)来向对象询问数据,这揭示了对象的内部实现。我也想在不将我当前的 UI(控制台)硬编码到对象本身的情况下做到这一点。

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

避免吸气剂

我可以通过对 UI 进行硬编码来避免吸气剂:

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

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

避免硬编码的 UI

我可以通过使用 getter 来避免硬编码的 UI:

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

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

可以避免两者吗?在上面的例子中我该怎么做?

注意:为了响应一些初步的答案,getter 不是遵循命名约定的方法getSomeFieldName。因此,重命名getSomeFieldNameaMethodThatIsNotPrefixedByGet不是解决方案。getter 是一种将私有数据从对象传递到调用它的作用域的方法。

完全清楚的是,我在这里要处理的问题与数据封装有关(因为这个问题被标记了)。如何防止将数据传递给不需要知道该数据的对象并且仍然避免对 UI 进行硬编码?

此外,基于这些 问题 我认为不应以许多答案所建议的方式使用 toString 。toString 似乎用于生成对象的文本表示以进行调试等,而不是用于返回任意输出,尤其是不用于返回依赖于应用程序的输出。

4

6 回答 6

3

是的去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 + '!';
        }
}
于 2011-04-11T06:48:15.477 回答
1
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);
}
于 2011-07-01T04:41:47.453 回答
1

您可以在 Warrior 类中覆盖 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);
于 2011-04-11T06:47:37.153 回答
1

我会在 Warrior 和 Weapon 中重写 toString() 方法,因为这个方法自然会返回一个对象的字符串表示。然后我将创建一个专门用于创建描述的类,例如 a DescriptionMaker,并在其中创建一个方法:

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

然后可以将该方法的返回值打印到控制台。此外,可以在DescriptionMaker课堂上应用内化。

于 2011-04-11T06:47:48.010 回答
1

在这种情况下,getter 对我来说似乎是一个很好的做法,因为它们允许您将数据(Warrior 和 Weapon 类)与您的 UI(调用 getter 并创建描述字符串、小部件、html 代码等)分开。但是我不会让 Warrior getter 创建字符串,它只会返回战士描述,UI 类会创建字符串(Warrior.getDescription()您建议在示例中执行的方法)。

于 2011-04-11T06:52:49.123 回答
0

如何将两者结合起来:

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

}

//Weapon class
public String display() 
{
  return name;
}
于 2011-04-11T06:47:24.147 回答