成语的容器类
我被告知根据以下代码示例开发我的代码:
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?