If an object has a property that is a collection, should the object create the collection object or make a consumer check for null? I know the consumer should not assume, just wondering if most people create the collection object if it is never added to.
如果对象具有属于集合的属性,那么对象是应该创建集合对象还是让使用者检查null?我知道消费者不应该假设,只是想知道大多数人是否创建了集合对象,如果它从未被添加到。
10 个解决方案
#1
7
You can also use the "Lazy initailizer" pattern where the collection is not initialized until (and unless) someone accesses the property getter for it... This avoids the overhead of creating it in those cases where the parent object is instantiated for some other purpose that does not require the collection...
您也可以使用“Lazy initailizer”模式,其中集合未初始化,直到(并且除非)有人访问它的属性getter ...这避免了在父对象被实例化为某些其他情况的情况下创建它的开销。不需要收集的目的......
public class Division
{
private int divId;
public int DivisionId { get; set; }
private Collection<Employee> emps;
public Collection<Employee> Employees
{ get {return emps?? (emps = new Collection<Employee>(DivisionId));}}
}
EDIT: This implementation pattern is, in general, not thread safe... emps could be read by two different threads as null before first thread finishes modifying it. In this case, it probably does not matter as DivisionId is immutable and although both threads would get different collections, they would both be valid. Whne the second thread fihishes, therefore, emps would be a valid collection. The 'probably' is because it might be possible for the first thread to start using emps before the second thread resets it. That would not be thread-safe. Another slightly more complex implementation from Jon SKeet is thread-safe (see This article on SIngletons for his example/discussion on how to fix this.
编辑:这个实现模式通常不是线程安全的......在第一个线程完成修改之前,emps可以被两个不同的线程读取为null。在这种情况下,它可能无关紧要,因为DivisionId是不可变的,虽然两个线程都会得到不同的集合,但它们都是有效的。因此,当第二个线程掠过时,emps将是一个有效的集合。 '可能'是因为第一个线程可能在第二个线程重置之前开始使用emps。这不是线程安全的。 Jon SKeet的另一个稍微复杂的实现是线程安全的(参见本文关于SIngletons的例子/讨论如何解决这个问题。
#2
3
This depends on the contract you have between your API and the user.
这取决于您与API和用户之间的合同。
Personally, I like a contract that makes the Object manage its collections, i.e., instantiating them on creation, and ensuring that they can't be set to null via a setter - possibly by providing methods to manage the collection rather than setting the collection itself.
就个人而言,我喜欢让Object管理其集合的合同,即在创建时实例化它们,并确保它们不能通过setter设置为null - 可能通过提供管理集合的方法而不是设置集合本身。
i.e., addFoo(Foo toAdd) instead of setFooSet(Set set), and so on.
即,addFoo(Foo toAdd)而不是setFooSet(Set set),依此类推。
But it's up to you.
但这取决于你。
#3
2
I typically will create the collection then provide methods to add / remove items from the internal collection rather than making the consumer of the class worry about checking for null. This also gives you the ability to control better what happens to the collection. Ultimately it depends on what it is for, but most likely if your class has a collection it isn't just so that the consumer of the class can have a collection of those objects. Otherwise, why would they use your class?
我通常会创建集合,然后提供从内部集合添加/删除项目的方法,而不是让类的使用者担心检查null。这也使您能够更好地控制集合中发生的事情。最终它取决于它的用途,但最有可能的是,如果你的类有一个集合,那么这个集合的消费者不仅可以拥有这些对象的集合。否则,为什么他们会使用你的课程?
#4
2
While what I say here is not universal by any means, I think collections are mostly suited as private properties which should be accessed by public methods on the object itself. Therefore, the object is responsible to create and destroy them as needed. This way, it won't be possible to set it to null from external code.
虽然我在这里所说的并不是通用的,但我认为集合最适合作为私有属性,应该通过对象本身的公共方法来访问。因此,对象负责根据需要创建和销毁它们。这样,就无法从外部代码将其设置为null。
#5
2
I prefer to create the collection upon instantiation, provide add/remove methods in the containing object, and if needed, provide addAll/removeAll methods for adding and removing entire external collections. I never allow the collection object to be accessed for get or set by the caller - I may, however, provide a getter that returns a copy (poss. immutable) of the collection.
我更喜欢在实例化时创建集合,在包含对象中提供添加/删除方法,如果需要,还提供addAll / removeAll方法来添加和删除整个外部集合。我从不允许调用者访问或设置集合对象 - 但是,我可以提供一个返回集合的副本(可能是不可变的)的getter。
I have also had copy-on-write implementations which provide an immutably wrapped view, since any mutation will create a new underlying collection.
我还有写入时复制实现,它提供了一个不可变的包装视图,因为任何突变都会创建一个新的底层集合。
#6
1
I create an empty collection. Sure, it has a slight memory cost, but not a large enough one to be concerned about it.
我创建了一个空集合。当然,它有一点点内存成本,但不足以引起人们的关注。
#7
1
IMO, this is where IEnumerable comes in nicely.
IMO,这是IEnumerable很好的地方。
Personally, I like my 'collection' properties to be initialized to empty lists.
就个人而言,我喜欢将我的“集合”属性初始化为空列表。
#8
1
If the collection is an intrinsic part of the object, then the object should generally create it (and not allow the user to set it to a different collection instance).
如果集合是对象的固有部分,那么对象通常应该创建它(并且不允许用户将其设置为不同的集合实例)。
#9
1
I've tried both ways and I am usually happy when I find I have already instanciated it. Alternatively you could hide the the implementation from the consumer behind a set of methods that can handle the check for you.
我已经尝试了两种方式,当我发现我已经实现了它时,我通常很高兴。或者,您可以隐藏一组可以为您处理检查的方法背后的消费者实现。
#10
0
As a general rule, I think the object should create the collection and provide methods for manipulating it; add/get/remove. When following this rule, you should not provide methods for setting the collection directly. If you want a method like setSomeCollection(Collection someCollection) for convenience, the implementation of this method should not set the reference within the object, but copy the values from the method parameter collection to the collection within the object;
作为一般规则,我认为对象应该创建集合并提供操作它的方法;添加/获取/删除。遵循此规则时,不应提供直接设置集合的方法。如果你想要一个类似setSomeCollection(Collection someCollection)这样的方法,那么这个方法的实现不应该在对象中设置引用,而是将方法参数集合中的值复制到对象中的集合中;
public void setSomeCollection(Collection someCollection) {
this.someCollection.clear();
this.someCollection.addAll(someCollection);
}
You should do this, so clients of your API cannot get access to the collection that your class maintains. If they do, they can manipulate it without using objects of your class and violate constraints that your class guarantees.
您应该这样做,因此API的客户端无法访问您的类所维护的集合。如果他们这样做,他们可以在不使用你的类的对象的情况下操纵它,并违反你的类所保证的约束。
The same is true if providing a getter; you should either return a copy of your internal colleciton, or a read-only version of it. Apache commons-collections and google-collections provide methods for creating immutable wrappers around a collection, aswell as the ones that come with Java in the java.util package; java.util.Collections.unmodifiable*.
如果提供吸气剂也是如此;你应该返回内部集合的副本,或者它的只读版本。 Apache commons-collections和google-collections提供了在集合中创建不可变包装器的方法,以及java.util包中随Java附带的方法。 java.util.Collections.unmodifiable *。
#1
7
You can also use the "Lazy initailizer" pattern where the collection is not initialized until (and unless) someone accesses the property getter for it... This avoids the overhead of creating it in those cases where the parent object is instantiated for some other purpose that does not require the collection...
您也可以使用“Lazy initailizer”模式,其中集合未初始化,直到(并且除非)有人访问它的属性getter ...这避免了在父对象被实例化为某些其他情况的情况下创建它的开销。不需要收集的目的......
public class Division
{
private int divId;
public int DivisionId { get; set; }
private Collection<Employee> emps;
public Collection<Employee> Employees
{ get {return emps?? (emps = new Collection<Employee>(DivisionId));}}
}
EDIT: This implementation pattern is, in general, not thread safe... emps could be read by two different threads as null before first thread finishes modifying it. In this case, it probably does not matter as DivisionId is immutable and although both threads would get different collections, they would both be valid. Whne the second thread fihishes, therefore, emps would be a valid collection. The 'probably' is because it might be possible for the first thread to start using emps before the second thread resets it. That would not be thread-safe. Another slightly more complex implementation from Jon SKeet is thread-safe (see This article on SIngletons for his example/discussion on how to fix this.
编辑:这个实现模式通常不是线程安全的......在第一个线程完成修改之前,emps可以被两个不同的线程读取为null。在这种情况下,它可能无关紧要,因为DivisionId是不可变的,虽然两个线程都会得到不同的集合,但它们都是有效的。因此,当第二个线程掠过时,emps将是一个有效的集合。 '可能'是因为第一个线程可能在第二个线程重置之前开始使用emps。这不是线程安全的。 Jon SKeet的另一个稍微复杂的实现是线程安全的(参见本文关于SIngletons的例子/讨论如何解决这个问题。
#2
3
This depends on the contract you have between your API and the user.
这取决于您与API和用户之间的合同。
Personally, I like a contract that makes the Object manage its collections, i.e., instantiating them on creation, and ensuring that they can't be set to null via a setter - possibly by providing methods to manage the collection rather than setting the collection itself.
就个人而言,我喜欢让Object管理其集合的合同,即在创建时实例化它们,并确保它们不能通过setter设置为null - 可能通过提供管理集合的方法而不是设置集合本身。
i.e., addFoo(Foo toAdd) instead of setFooSet(Set set), and so on.
即,addFoo(Foo toAdd)而不是setFooSet(Set set),依此类推。
But it's up to you.
但这取决于你。
#3
2
I typically will create the collection then provide methods to add / remove items from the internal collection rather than making the consumer of the class worry about checking for null. This also gives you the ability to control better what happens to the collection. Ultimately it depends on what it is for, but most likely if your class has a collection it isn't just so that the consumer of the class can have a collection of those objects. Otherwise, why would they use your class?
我通常会创建集合,然后提供从内部集合添加/删除项目的方法,而不是让类的使用者担心检查null。这也使您能够更好地控制集合中发生的事情。最终它取决于它的用途,但最有可能的是,如果你的类有一个集合,那么这个集合的消费者不仅可以拥有这些对象的集合。否则,为什么他们会使用你的课程?
#4
2
While what I say here is not universal by any means, I think collections are mostly suited as private properties which should be accessed by public methods on the object itself. Therefore, the object is responsible to create and destroy them as needed. This way, it won't be possible to set it to null from external code.
虽然我在这里所说的并不是通用的,但我认为集合最适合作为私有属性,应该通过对象本身的公共方法来访问。因此,对象负责根据需要创建和销毁它们。这样,就无法从外部代码将其设置为null。
#5
2
I prefer to create the collection upon instantiation, provide add/remove methods in the containing object, and if needed, provide addAll/removeAll methods for adding and removing entire external collections. I never allow the collection object to be accessed for get or set by the caller - I may, however, provide a getter that returns a copy (poss. immutable) of the collection.
我更喜欢在实例化时创建集合,在包含对象中提供添加/删除方法,如果需要,还提供addAll / removeAll方法来添加和删除整个外部集合。我从不允许调用者访问或设置集合对象 - 但是,我可以提供一个返回集合的副本(可能是不可变的)的getter。
I have also had copy-on-write implementations which provide an immutably wrapped view, since any mutation will create a new underlying collection.
我还有写入时复制实现,它提供了一个不可变的包装视图,因为任何突变都会创建一个新的底层集合。
#6
1
I create an empty collection. Sure, it has a slight memory cost, but not a large enough one to be concerned about it.
我创建了一个空集合。当然,它有一点点内存成本,但不足以引起人们的关注。
#7
1
IMO, this is where IEnumerable comes in nicely.
IMO,这是IEnumerable很好的地方。
Personally, I like my 'collection' properties to be initialized to empty lists.
就个人而言,我喜欢将我的“集合”属性初始化为空列表。
#8
1
If the collection is an intrinsic part of the object, then the object should generally create it (and not allow the user to set it to a different collection instance).
如果集合是对象的固有部分,那么对象通常应该创建它(并且不允许用户将其设置为不同的集合实例)。
#9
1
I've tried both ways and I am usually happy when I find I have already instanciated it. Alternatively you could hide the the implementation from the consumer behind a set of methods that can handle the check for you.
我已经尝试了两种方式,当我发现我已经实现了它时,我通常很高兴。或者,您可以隐藏一组可以为您处理检查的方法背后的消费者实现。
#10
0
As a general rule, I think the object should create the collection and provide methods for manipulating it; add/get/remove. When following this rule, you should not provide methods for setting the collection directly. If you want a method like setSomeCollection(Collection someCollection) for convenience, the implementation of this method should not set the reference within the object, but copy the values from the method parameter collection to the collection within the object;
作为一般规则,我认为对象应该创建集合并提供操作它的方法;添加/获取/删除。遵循此规则时,不应提供直接设置集合的方法。如果你想要一个类似setSomeCollection(Collection someCollection)这样的方法,那么这个方法的实现不应该在对象中设置引用,而是将方法参数集合中的值复制到对象中的集合中;
public void setSomeCollection(Collection someCollection) {
this.someCollection.clear();
this.someCollection.addAll(someCollection);
}
You should do this, so clients of your API cannot get access to the collection that your class maintains. If they do, they can manipulate it without using objects of your class and violate constraints that your class guarantees.
您应该这样做,因此API的客户端无法访问您的类所维护的集合。如果他们这样做,他们可以在不使用你的类的对象的情况下操纵它,并违反你的类所保证的约束。
The same is true if providing a getter; you should either return a copy of your internal colleciton, or a read-only version of it. Apache commons-collections and google-collections provide methods for creating immutable wrappers around a collection, aswell as the ones that come with Java in the java.util package; java.util.Collections.unmodifiable*.
如果提供吸气剂也是如此;你应该返回内部集合的副本,或者它的只读版本。 Apache commons-collections和google-collections提供了在集合中创建不可变包装器的方法,以及java.util包中随Java附带的方法。 java.util.Collections.unmodifiable *。