如何避免使用getter并避免对UI进行硬编码?

时间:2011-04-11 06:41:19

标签: java encapsulation getter tell-dont-ask

我想在控制台上打印一个战士的描述,其中包括战士的力量和战士的武器,格式为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进行硬编码来避免使用getter:

//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的方法。因此,将getSomeFieldName重命名为aMethodThatIsNotPrefixedByGet不是解决方案。 getter是一种将私有数据从对象传递到调用它的作用域的方法。

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

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

6 个答案:

答案 0 :(得分: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 + '!';
        }
}

答案 1 :(得分:1)

你可以在你的Warrior类中重写toString来实现它。

public String toString() {


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

}

覆盖toString inWeapon以返回名称;

as

public String toString() {

    return this.name;

    }

您可以直接打印

System.out.println(warrior);

答案 2 :(得分:1)

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

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

然后可以将此方法的返回值打印到控制台。此外,内部化可以应用于DescriptionMaker类。

答案 3 :(得分:1)

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

答案 4 :(得分: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);
}

答案 5 :(得分:0)

如何将两者结合起来:

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

}

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