在 Java 中打印给用户的正确方法是什么
What is the proper way to print to user in Java
我的计算机科学老师告诉我,我不应该从 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 中打印任何内容,只是您模糊了数据类型。帐户(不是真正的银行)的 balance
大概是数字类型(int
、long
)而不是 String
。
总的来说,让你的方法做对一件事。通过在 getter 中打印一些内容并返回可以进行调试,但通常不建议这样做。这就是你老师的意思。
编写具有明确定义和类型安全 API 的 类 非常有用且重要,尤其是在 Java.
中
你的老师是对的。
getBalance 方法的目的是 "get" 以您的应用程序的其他部分可以使用的方式平衡。余额的使用方式有很多种,包括打印(在不同的地方/以不同的方式)将其添加到电子表格中,将其添加到总数中等等。
如果您将 getBalance()
方法设计为仅格式化和打印余额(到标准输出),那么所有其他事情都需要其他方法......对于其他事情。
软件工程中有一个原则叫“separation of concerns”。 class(或更一般地说,模块)应该做它需要做的事情,并将其他事情留给 classes 方法的调用者。在这种情况下,我们是在细粒度级别上讨论 SoC……但该原则也适用于此级别。
你老师让你写的版本对我来说更有意义。作为您 Java classes 的用户,我更喜欢以数字形式获取余额,然后按我希望的方式使用它。将数据显示为美元字符串显然是一个有效的用例,但不是我能想到的唯一一个。假设,作为您 class 的客户,我想知道我的帐户可以获得多少欧元、英镑或卢比,那么第二种实现方式更适合我。
您的老师可能建议银行不负责如何将余额显示为字符串,因为使用银行的不同人可能希望以不同方式显示余额。
解决这个问题的一种方法是按照教授的建议简单地保留银行,并在获得余额后按照自己的方式格式化。
第二种方法是制作您自己的格式化程序 class 以您想要的方式格式化字符串:
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 子class 并让它知道如何按照您喜欢的方式进行格式化(尽管这使得改变一家银行的行为方式变得更加困难,而第三种方法回调还允许您即时更改行为),但首先想到的是这三种方式。
我的计算机科学老师告诉我,我不应该从 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 中打印任何内容,只是您模糊了数据类型。帐户(不是真正的银行)的 balance
大概是数字类型(int
、long
)而不是 String
。
总的来说,让你的方法做对一件事。通过在 getter 中打印一些内容并返回可以进行调试,但通常不建议这样做。这就是你老师的意思。
编写具有明确定义和类型安全 API 的 类 非常有用且重要,尤其是在 Java.
中你的老师是对的。
getBalance 方法的目的是 "get" 以您的应用程序的其他部分可以使用的方式平衡。余额的使用方式有很多种,包括打印(在不同的地方/以不同的方式)将其添加到电子表格中,将其添加到总数中等等。
如果您将 getBalance()
方法设计为仅格式化和打印余额(到标准输出),那么所有其他事情都需要其他方法......对于其他事情。
软件工程中有一个原则叫“separation of concerns”。 class(或更一般地说,模块)应该做它需要做的事情,并将其他事情留给 classes 方法的调用者。在这种情况下,我们是在细粒度级别上讨论 SoC……但该原则也适用于此级别。
你老师让你写的版本对我来说更有意义。作为您 Java classes 的用户,我更喜欢以数字形式获取余额,然后按我希望的方式使用它。将数据显示为美元字符串显然是一个有效的用例,但不是我能想到的唯一一个。假设,作为您 class 的客户,我想知道我的帐户可以获得多少欧元、英镑或卢比,那么第二种实现方式更适合我。
您的老师可能建议银行不负责如何将余额显示为字符串,因为使用银行的不同人可能希望以不同方式显示余额。
解决这个问题的一种方法是按照教授的建议简单地保留银行,并在获得余额后按照自己的方式格式化。
第二种方法是制作您自己的格式化程序 class 以您想要的方式格式化字符串:
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 子class 并让它知道如何按照您喜欢的方式进行格式化(尽管这使得改变一家银行的行为方式变得更加困难,而第三种方法回调还允许您即时更改行为),但首先想到的是这三种方式。