成语的容器类

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

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

Class Dog{
   // Attributes and methods
}

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


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

这意味着你的所有其他代码将只引用(即使用) Dogs类,但不引用内部列表。 这反过来又意味着,无论你决定从列表切换到内部使用普通数组(或者以任何其他方式改变Dogs的实现,就此而言),你都可以轻松地做到这一点。

这是一个动机。 至于“更好”的问题,这取决于是否可以通过稳定的Dogs的API来限制内部容器的使用。 如果可以的话,创建一个Dogs类是有道理的。 否则,只需继续并使用List即可更简单,更轻松。

上述“稳定的API”的一个例子是Visitor模式的应用。 在这种情况下, Dogs类应该有一个visit()参数的单个visit()方法。 访客'知道'如何处理Dog ,但完全不知道Dogs内部结构。 这是一件好事。


我可以看到为什么有人要求你这样做,虽然就像其他答案所表明的那样,但这个问题太宽泛,无法正确回答。 取决于场景。

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

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

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

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

我看不出有什么理由让一个单独的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实例,而不是其他任何东西。

链接地址: http://www.djcxy.com/p/53935.html

上一篇: Idiom for container classes

下一篇: How do you find an element index in a Collection<T> inherited class?