成语的容器类
我被告知根据以下代码示例开发我的代码:
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实例,而不是其他任何东西。
上一篇: Idiom for container classes
下一篇: How do you find an element index in a Collection<T> inherited class?
