【问题标题】:Java - Is it ok to have a method that passes private field values into another class' method?Java - 可以将私有字段值传递给另一个类的方法吗?
【发布时间】:2013-03-31 17:41:35
【问题描述】:

我有一个包含一堆字段的类,所有字段都是私有的(子类使用受保护的 getter 访问一些)。我需要将这些字段中的大部分传递到另一个类中的方法中,该方法将格式化它们并生成输出。可以在类中有一个方法与将它们全部传递的字段吗?或者这些情况是否表明我应该在两个类之间实现一些其他关系,因为它们看起来因此紧密耦合?

更多信息:A 类代表员工,B 类的唯一职责是格式化程序的输出。

【问题讨论】:

  • 您是否需要将输出格式与Employee 分离?如果是这样,我建议使用ResourceBundle 进行格式化并将方法保留在Employee 类中。
  • 谢谢,我第一次听说 ResourceBundle(我是新手),现在正在查找。

标签: java class parameter-passing field private-members


【解决方案1】:

您是在问是否可以执行以下操作?

public class A {
 private B myB = new B();
 private String myUnformattedName = "some information";

 public String getFormattedInfo() {
   return myB.formatInfo(myUnformattedName);
 }
}

没关系。

Marking a field as private just means that only the containing class should be able to access it...

如果你的意思是别的,最好在你的问题中弹出一些代码给人们上下文


好的,因此无法在此处设置值,但您可以在此处看到调用格式化程序的两种不同方式。当参数列表超过三四个项目时,就会变得难以阅读。

在这种情况下,我只需将 A 传递给格式化程序,并为您希望 B 能够读取的每个值都有一个 get 方法。

public class A {
 private B myB = new B();
 private String myUnformattedName = "some information";
 private String myUnformattedNameOne = "some information";
 private String myUnformattedNameTwo = "some information";
 private String myUnformattedNameThree = "some information";
 private String myUnformattedNameFour = "some information";
 private String myUnformattedNameFive = "some information";
 private String myUnformattedNameSix = "some information";

 public String getFormattedInfo() {
   //pass the object itself and use get methods
   return myB.formatInfo(this); 
 }

 public String getFormattedInfoLong() {
   //this is OK but gets difficult to read the longer the 
   //parameter list gets
   return myB.formatInfo(myUnformattedName, myUnformattedNameOne, 
      myUnformattedTwo, myUnformattedNameThree, myUnformattedNameFour,
      myUnformattedNameFive, myUnformattedNameSix); 
 }

 //getters
 public String getUnformattedName() {
    return myUnformattedName;
 }

 public String getUnformattedNameOne() {
    return myUnformattedNameOne;
 }

 //etc

}

【讨论】:

  • 是的,看起来像!谢谢。
  • hm,实际上可以通过getFormattedInfo()方法将大量字段(字符串和双精度)作为参数同时传递给B对象吗?
  • 是的,它只是一个风格的东西然后......如果参数列表变得“太长”,那么给字段获取器并传递对象本身。
【解决方案2】:

我实际上建议使用访问者模式。

A 类有一个接受访问者的方法,而访问者又拥有一个定义良好的公共方法,例如:

首先,被访问的类允许某些具有良好定义接口的类进入,不会将自己的数据传递给外部。

public class A {
    int data;

    public void getFormattedBy(Formatter f) {
       f.format(data);
    }
}

访问者的界面,允许多种格式化程序

public interface Formatter {
    void format (int data);
}

一个格式化程序,允许进入访问的类。

public class B implements Formatter {
    public void format(int data) {
        // do the formatting and printing
    }
}

这样你只需调用

A a = new A();
B b = new B(); // the formatter
a.getFormattedBy(b);

最终,访问者(格式化程序)可以访问许多允许访问者进入的类(可能通过自己实现接口),并且访问的类可以被许多访问者访问。

【讨论】:

    【解决方案3】:

    我认为传递它们是完全可以的,只要它们具有原始类型或不可变。

    如果被调用者可以在不应该修改它们的时候修改它们,那么你有一个设计问题。

    【讨论】:

    • 太好了,谢谢!它们要么是字符串,要么是双打,不应该被修改。通过“不可变”,我猜如果字符串字段是私有的/设置的方法仅在原始类+子类中可见,那没关系?
    • 不可变类一旦创建就不能更改。所以一切都在构造函数中完成,没有mutators(setter),只有getter。如果需要,甚至 getter 也会生成它们返回的数据的防御性副本。像 String 这样的 Java 类遵守这一点。
    【解决方案4】:

    只要 B 类不修改它们就可以了。如果该类确实如此,则将不可变实例传递给它。

    【讨论】:

      【解决方案5】:

      您可以将 B 类设为实用程序类,并且仅在其上具有静态方法。

      然后在你的 A 类中你可以有这样的东西:

      公共字符串格式MyVariables() {

      返回 B.format(a,b,c,d);

      }

      我假设你提到的输出是一个字符串,但它实际上可以是任何东西。

      【讨论】:

        【解决方案6】:

        您应该考虑,如果您的 Employee 字段是原始值(intboolean)或不可变值(例如 String),那么您可以让其他类读取它们而无需担心。

        使用private 保护字段是不暴露对象内部工作的方法,该对象只能通过其public API 访问。但是,当您的类真正代表一个业务对象(即标识实体的一组值)时,让其他人读取内部字段是完全安全的。

        【讨论】:

          【解决方案7】:

          传输数据的最佳方式是 DTO 对象。

          这些对象仅包含实例变量(带有 setter 和 getter)作为您要传输的数据!

          这个类中不应该有任何行为

          例如,如果你想传递一个员工数据,请执行以下操作

          class EmployeeBean
          {
          private String name;
          private String age;
          
          public void setName(String n)
          {
          name=n;
          }
          
          public String getName()
          {
          return name;
          }
          
          
          public void setAge(int n)
          {
          age=n;
          }
          
          public int getAge()
          {
          return age;
          }
          
          }
          

          您现在可以创建 EmployeeBean 类,在其实例变量中填充数据,然后将此对象作为参数传递给另一个可以对其进行格式化的类中的方法

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-12
            • 2022-01-16
            • 2012-10-11
            • 1970-01-01
            • 2012-07-07
            相关资源
            最近更新 更多