容器类的成语

时间:2014-05-13 13:04:10

标签: java class containers idioms

我被告知根据以下代码示例开发我的代码:

Class Dogs{
   List<Dog> listOfDogs = new ArrayList<Dog>();
   // Setters, getters...
}

Class Dog{
   // Attributes and methods
}

问题是:为什么将Dogs类实现为Dog对象的ArrayList的容器更好,而不是仅仅引用一个简单的ArrayList。 这被认为是封装吗?

7 个答案:

答案 0 :(得分:4)

我认为没有理由创建一个单独的Dogs类,除非除了添加,删除和访问成员的标准集合操作之外还要在Dogs上执行其他操作。例如,如果有releaseTheHounds()方法或callEveryoneForDinner()方法等,

但是,可能是您被告知的是,您应该使用List类型来声明listOfDogs,而不是ArrayList。就是这样:

List listOfDogs = new ArrayList<Dog>();

而不是:

ArrayList listOfDogs = new ArrayList<Dog>();

你已经这样做了,这是一个很好的做法。这里,“封装”是隐藏ArrayList作为List接口的实现者。这样可以轻松切换到其他实现(例如TreeList),而无需更改访问listOfDogs的任何代码。

最后但并非最不重要的,你真的应该这样声明:

List<Dog> listOfDogs = new ArrayList<Dog>();

然后,您确保List保留Dog个实例,而不是其他任何内容。

答案 1 :(得分:4)

我可以看到为什么有人要求你这样做,尽管就像其他答案所暗示的那样,这是一个过于宽泛的问题无法正确回答。取决于场景。

现在,这里的理由可能是当你有一个Dog对象的容器时,你可以控制如何创建,访问和更改这些对象。如果你只有一个列表,你无法真正控制正确的访问或添加/删除操作。但是,如果你有狗类。您可以返回只读列表,不允许添加特定品种的狗等。它基本上可以作为所有与狗有关的控制器类。

Class Dogs
{
  List listofDogs = new ArrayList<Dog>();

  public void AddDog(Dog newDog)
  {
     //check if valid
  }

  public List<Dog> getDogs()
  {
    //return readonly dogs collection
  }
}

答案 2 :(得分:4)

基本上,创建Dogs类可为您提供额外的间接层。

这意味着您的所有其他代码将仅引用(即使用)Dogs类,而不引用内部列表。反过来,这意味着无论何时您决定从使用列表切换到内部使用普通数组(或以任何其他方式更改Dogs的实现),您都可以随便这样做。

这是它的动力。至于它是否更好等问题,这在很大程度上取决于您是否可以通过稳定的Dogs API来限制内部容器的使用。如果可以,创建Dogs类是合理的。否则,只需继续使用List即可。更简单,更容易。

上述稳定API的一个例子&#39;是访客模式的应用程序。在这种情况下,Dogs类应该有一个visit()方法接受访问者参数。访客&#39;知道&#39;如何处理Dog,但完全不知道Dogs内部结构。这是件好事。

答案 3 :(得分:1)

使用我使用的mvc框架

使得对webforms的序列化更容易一些

答案 4 :(得分:1)

这取决于您的问题以及您要对该数组列表执行的操作。您可能希望扩展ArrayList的某些操作或添加将应用于所有数组列表项的新操作,例如对方法进行排序此列表按顺序排列。

答案 5 :(得分:0)

我相信他们可能希望你们做一些类似“对象池模式”的事情。对象池设计模式是一种创建设计模式,可以在处理实例化缓慢的类时提高性能。不是构造新对象,而是根据需要从池中检索可释放对象并将其释放到池中。

在这种情况下,Dogs将成为Pool,Dog将成为PooledObject,并且任何使用PooledObject类型对象的类都将成为客户端。

答案 6 :(得分:0)

当我们有一组对一组对象典型的方法时,我们使用这样的实现。因此,我们不关注特定的表示选择,而是关注共享的操作和属性。例如,堆栈使用此模式,堆栈上通常可用的操作如下:push,remove,确定堆栈是否为空等等。而不是Dog,它使用Object;所以你可以堆叠任何对象。

现在你可以添加除Dog以外的对象,它们将共享相同的方法。