【问题标题】:What is the proper way to print to user in Java [closed]用Java向用户打印的正确方法是什么[关闭]
【发布时间】:2016-11-16 16:46:25
【问题描述】:

我的计算机科学老师告诉我,我不应该从 getter 等方法打印字符串,而应该从 main 方法打印给用户。我想知道从哪里打印是否重要,以及构建代码的正确方法是什么。

例如:

public class Main {
    public static void main(String[] args) throws IOException {
        Bank bank = new Bank(20);
        System.out.println(bank.getBalance());
    }
}

public class Bank {
    int balance;

    public Bank(int balance){
        this.balance = balance;
    }

    public String getBalance(){
        return "You have $" + this.balance;
    }
}

而不是我的老师说我应该写它

public class Main {
    public static void main(String[] args) throws IOException {
        Bank bank = new Bank(20);
        System.out.println("You have $" + bank.getBalance());
    }
}

public class Bank{
    int balance;

    public Bank(int balance){
        this.balance = balance;
    }

    public int getBalance(){
        return this.balance;
    }
}

【问题讨论】:

  • 括号放置在程序结构方面比打印语句的放置更让我担心。也就是说,只要从最终程序中删除那些打印语句,通常可以在 getter 内部打印。如果不在其中编写打印语句,通常很难知道 getter 内部发生了什么。一种方法是传递一个回调接口或 null,如果它在那里,它将执行你的回调,否则什么都不做,但否则你将需要使用调试器来查看 getter 以确保它的行为正确,这通常更难。
  • 无论如何,您的教授可能不满意的是 getBalance 旨在返回余额,这应该是私有的,而不是余额字符串。如果您想以字符串形式获取余额,只需创建另一个方法 getBalanceString() 即可完成您所做的工作,而 getBalance 应该只返回余额。此外,余额字符串可能应该由主而不是银行管理,因为使用银行的不同人可能希望以不同的方式显示余额。

标签: java class printing main


【解决方案1】:

你的老师是对的。

你并没有真正在你的 getter 中打印任何东西,只是你掩盖了数据类型。帐户(不是真正的银行)的balance 可能是数字类型(intlong)而不是String

一般来说,让你的方法正确地做一件事。通过在你的 getter 中打印一些东西并返回是可以调试的,但通常不建议这样做。这就是你老师的意思。

编写具有良好定义和类型安全 API 的类非常有用且重要,尤其是在 Java 中。

【讨论】:

  • 1 和 2 对我来说听起来是一样的。
【解决方案2】:

你的老师是对的。

getBalance 方法的目的是以应用程序的其他部分可以使用的方式“获取”余额。有很多方法可以使用天平,包括打印(在不同的地方/不同的方式)将其添加到电子表格中,将其添加到总计中等等。

如果您将 getBalance() 方法设计为仅格式化和打印余额(到标准输出),那么所有其他事情都需要其他方法......对于彼此的事情。

软件工程中有一个原则被称为“separation of concerns”。一个类(或更一般地,一个模块)应该做它需要做的事情,而将其他事情留给类方法的调用者。在这种情况下,我们讨论的是细粒度级别的 SoC……但该原则也适用于该级别。

【讨论】:

    【解决方案3】:

    你的老师让你写的版本对我来说更有意义。作为 Java 类的用户,我更喜欢以数字形式获取余额,然后以任何我希望的方式使用它。将数据显示为美元字符串显然是一个有效的用例,但不是我能想到的唯一用例。假设,作为您班级的客户,我想知道我的帐户可以得到多少欧元、英镑或卢比,那么第二个实现会更适合我。

    【讨论】:

      【解决方案4】:

      您的老师可能建议银行不应该负责如何将余额显示为字符串,因为使用银行的不同人可能希望以不同的方式显示余额。

      解决此问题的一种方法是按照教授的建议保留银行,并在获得余额编号后以自己的方式对其进行格式化。

      第二种方法是制作自己的格式化程序类,以您想要的方式格式化字符串:

      public class Main2 
      {     
          public Main2() {
              Bank bank = new Bank(20);
              System.out.println(BalanceFormat.formatBalance(bank.getBalance()));
          }
      
          public static void main(String[] args) {
              new Main2();
          }
      }
      
      class Bank {
          private int balance;
      
          public Bank(int balance) {
              this.balance = balance;
          }
      
          public int getBalance() {
              return balance;
          }
      }
      
      
      class BalanceFormat 
      {
          public static String formatBalance(int balance) {
              return ("Your balance is $" + balance);    
          }
      }   
      

      执行此操作的第三种方法是通过回调,通过这种方式您可以告诉银行您希望它在保持其默认值的同时如何表现。

      public class Main 
      {    
          public Main() 
          {
              Bank bank = new Bank(20);
              System.out.println(bank.getBalanceString());     
              Bank bank2 = new Bank(20, (balance) -> {
                  return ("Your balance is: $" + balance);
              });
              System.out.println(bank2.getBalanceString());             
          }
      
          public static void main(String[] args) 
          {        
              new Main();
          }
      
          private class Bank 
          {
              int balance;
              BalanceStringCallback bankPrintBehavior = null;
      
              public Bank(int balance, BalanceStringCallback callback) 
              {
                  this.bankPrintBehavior = callback;
                  this.balance = balance;
              }
      
              public Bank(int balance) 
              {
                  this.balance = balance;
              }
      
              public int getBalance() 
              {
                  return this.balance;
              }
      
              public String getBalanceString() 
              {
                  if (bankPrintBehavior == null) {
                      return String.valueOf(balance);
                  } else {
                      return (bankPrintBehavior.callback(balance));
                  }
              }
          }
      
          @FunctionalInterface
          private interface BalanceStringCallback 
          {
              abstract String callback(int balance);
          }    
      }
      

      还有其他方法,例如创建您自己的 Bank 子类并使其知道如何按照您喜欢的方式进行格式化(尽管这使得更改银行的行为方式变得更加困难,而回调的第三种方法也允许您更改动态的行为),但首先想到的是这三种方式。

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 2011-03-20
        • 2012-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多