简体   繁体   English

在类中声明方法的首选方法

[英]Preferred way of declaring methods in a class

I am having a doubt with method creations in a class for setting information. 我对类中的方法创建有疑问,用于设置信息。

  1. creating separate methods for setting each attribute 创建用于设置每个属性的单独方法

     class Address{ private String name; private String city; public setName(String name) { ... } public setCity(String name) { ... } } 
  2. creating single method for setting all attributes 创建用于设置所有属性的单一方法

     class Address{ private String name; private String city; public setAddress(String name,String city) { ... } } 

from above two ways which is preferable in memory point of view? 从以上两种方式来看,在记忆的观点上更可取?

Common practice is to use JavaBean style 通常的做法是使用JavaBean样式

class Address {
  private String name;
  private String city;

  public setName(String name){
    this.name = name;
  }

  public String getName() {
     return name;
  }

  public setCity(String city){
     this.city = city;
  }

  public getCity() {
    return city;
  }

} }

Another common practise, which is quite similar to you second approach is to create immutable object. 另一种常见的做法,与你的第二种方法非常相似,就是创建不可变对象。 Parameters are passed to constructor instead of big setter method. 参数传递给构造函数而不是大的setter方法。

class Address {
  private final String name;
  private final String city;

  public Address(String name, String city) {
      this.name = name;
      this.city = city;
  }

  public String getName() {
     return name;
  }

  public getCity() {
    return city;
  }
}

From memory point of view, difference would be that second example is setting all attributes in constructor and all those attributes are immutable. 从内存的角度来看,不同之处在于第二个示例是在构造函数中设置所有属性,并且所有这些属性都是不可变的。 In general, object constructed this way are safer when used by multiple threads. 通常,当由多个线程使用时,以这种方式构造的对象更安全。

In second example, there is no need for synchronization. 在第二个例子中,不需要同步。 You'd need to handle synchronization/memory issues when multiple threads using standard JavaBean object. 当多个线程使用标准JavaBean对象时,您需要处理同步/内存问题。

I can't see how the two approaches would be any different memory-wise. 我看不出这两种方法在记忆方面会有什么不同。

Choose the approach that makes most sense to have in the interface of the class. 选择在类的界面中最有意义的方法。

I would recommend to go with approach 2 only if both properties are logically strongly related, or if there is some class invariant that you don't want to temporarily break (even temporarily). 我建议只使用方法2,如果两个属性在逻辑上强烈相关,或者如果有一些类不变,你不想暂时中断(甚至暂时)。

In your Address example, I would definitely go with two setter methods , since when talking about addresses, the name and city are quite unrelated. 在你的Address示例中,我肯定会使用两种setter方法 ,因为在谈论地址时,名称和城市是完全无关的。


For methods in general I'd say that whether or not you split a method up in two has little effect on memory consumption. 对于一般的方法,我会说你是否将方法分成两部分对内存消耗几乎没有影响。 Each object doesn't get its own set of methods allocated. 每个对象都没有分配自己的方法集。 The memory containing the methods is shared between all instances of a class. 包含这些方法的内存在类的所有实例之间共享。


Rule of thumb: Strive to make the interface of your class clean and logical. 经验法则: 努力使您的班级界面干净而合乎逻辑。

Why not to use method #2 为什么不使用方法#2

Your second example is not recommended because if you added a new field to the Address class, then do you add it into the existing setter method or do you create a new setter method? 建议不要使用第二个示例,因为如果向Address类添加了一个新字段,那么是将它添加到现有的setter方法中还是创建一个新的setter方法? If you add it into the existing setter method, then any classes that called that method would be broken. 如果将它添加到现有的setter方法中,那么调用该方法的任何类都将被破坏。 And if you created a new setter method, then it is confusing for anyone who wants to use that class why certain fields are grouped together that way while others are not. 如果你创建了一个新的setter方法,那么对于任何想要使用该类的人来说,为什么某些字段以这种方式组合在一起而其他字段没有组合在一起会让人感到困惑。

Using a separate setter method for each field that you wish to expose 对要显示的每个字段使用单独的setter方法

The common practice is to have a single setter method for each field in your class that you wish to expose (ie your first example). 通常的做法是为您希望公开的类中的每个字段设置一个setter方法(即您的第一个示例)。 Whether or not this is a good practice is debatable because it forces a class to be mutable. 这是否是一个好的做法是有争议的,因为它迫使一个类是可变的。 It is best to make an object immutable, if possible, for a number of reasons . 如果可能,最好使对象成为不可变的, 原因有很多

Initializing your fields using a constructor 使用构造函数初始化字段

One way to make a class immutable is by getting rid of the setter methods and instead making your fields settable via your class constructor, as below. 使类不可变的一种方法是删除setter方法,然后通过类构造函数设置字段,如下所示。 The downside to implementing it this way is that if your class has a lot of fields, it may potentially lead to large, unreadable constructor calls. 以这种方式实现它的缺点是,如果你的类有很多字段,它可能会导致大的,不可读的构造函数调用。

public class Address {
    public String name;
    public String city;

    private Address(String name, String city) {
        this.name = name;
        this.city = city;
    }
}

Initializing your fields using the Builder pattern 使用Builder模式初始化字段

Below is a completely alternative implementation (inspired by this article ) that is a variation of the Builder pattern. 下面是一个完全替代的实现(受本文启发),它是Builder模式的变体。 It simulates object mutability without sacrificing readability. 它模拟对象的可变性而不牺牲可读性。

public class Address {
    public String name;
    public String city;

    private Address() {}

    private void setName(String name) {
        this.name = name;
    }

    private void setCity(String city) {
        this.city = city;
    }

    static class Builder {
        private Address address = new Address();

        public Builder name(String name) {
            address.setName(name);
            return this;
        }

        public Builder city(String city) {
            address.setCity(city);
            return this;
        }

        public Address build() {
            return address;
        }
    }
}

With the above class, you could create an immutable instance of the Address class as follows: 使用上面的类,您可以创建Address类的不可变实例,如下所示:

Address address = new Address.Builder()
        .name("Mansoor's address")
        .city("Toronto")
        .build();

Which approach uses more memory? 哪种方法使用更多内存?

From a memory point of view, there shouldn't be any difference since the size of a class in memory is dependent on the fields in the class. 从内存的角度来看,应该没有任何区别,因为内存中类的大小取决于类中的字段。 Since all three implementations have the same fields, they should take the same amount of space in memory, regardless of which approach you use. 由于所有三个实现都具有相同的字段,因此无论使用哪种方法,它们都应在内存中占用相同的空间量。

This is not a clear question. 这不是一个明确的问题。 Do you mean, would you rather have two methods like setFoo(String) and setBar(int) , or one method like setFooBar(String, int) ? 你的意思是,你宁愿有两个方法,如setFoo(String)setBar(int) ,还是像setFooBar(String, int) It really depends on whether these are logically different properties, in which case you want individual methods, or whether it often (or only) makes sense to set them together. 这实际上取决于这些是否是逻辑上不同的属性,在这种情况下,您需要单独的方法,或者是否经常(或仅)将它们组合在一起是有意义的。 You could provide both. 你可以提供两者。

Neither has any impact on memory, no. 对记忆没有任何影响,没有。

The JavaBean standard is to have getters and setters for each property: http://en.wikibooks.org/wiki/Java_Programming/Java_Beans . JavaBean标准是为每个属性设置getter和setter: http//en.wikibooks.org/wiki/Java_Programming/Java_Beans If you don't want to follow that standard convention, its what makes the most sense for your shop. 如果您不想遵循该标准惯例,那么它对您的商店最有意义。 As per other answers on this thread, there probably is a minimal memory delta, if any. 根据此线程上的其他答案,可能存在最小内存增量(如果有)。

Nb.1 without a doubt. Nb.1毫无疑问。

And you don't write that code by hand, only declare your fields. 而且你不是手工编写代码,只是声明你的字段。

Then you let Eclipse do the rest for you. 然后你让Eclipse为你完成剩下的工作。

In Eclipse use Source --> generate getters and setters. 在Eclipse中使用Source - >生成getter和setter。

A very similar construct as #2 is done in the objects constructor. 在对象构造函数中完成了与#2非常相似的构造。

The updated question with regards to memory. 关于记忆的更新问题。 Don't worry one second in production code for the memory difference between those two ways. 在生产代码中不要担心这两种方式之间的内存差异。

You generally write a setter and a getter method for each attribute. 您通常为每个属性编写一个setter和getter方法。

I don't really see the case when one method is enough for setting all the attributes. 当一种方法足以设置所有属性时,我真的没有看到这种情况。 In this case, all attributes should have the same value? 在这种情况下,所有属性应该具有相同的值? Or you always would have to pass parameters for all attributes. 或者您总是必须传递所有属性的参数。 Both cases are not really what you want. 这两种情况都不是你想要的。 So you should clearly prefer your first approach. 所以你应该更喜欢你的第一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM