假设我有一个CityDistrict
类,如下所示:
class CityDistrict {
List<House> houses;
...
}
假设对于某些用例,ArrayList
最适合houses
,有时候更适合LinkedList
。您如何告诉CityDistrict创建它应该用于houses
我的三个想法是:
1)这是参数类的用例吗?像
这样的东西class CityDistrict<T> {
T<House> houses;
...
}
然后你可以创建一个CityDistrict<ArrayList>
。但我认为T应该属于List
类型的信息在这里丢失了。
2)或者您可以创建几个构造函数或静态工厂方法,如generateArrayListCityDistrict
,但我认为这有点难看。
3)在构造函数CityDistrict(int ListFlag)
中使用某种flag变量,并将1
映射到ArrayList
,依此类推。我认为也有点难看。
我在这里错过了明显的事吗?什么是干净和OOP处理这种情况的方法?
答案 0 :(得分:7)
您可以将Supplier<List<House>>
传递给构造函数。它将决定实例应该使用的实现:
class CityDistrict {
List<House> houses;
public CityDistrict(Supplier<List<House>> implementation) {
houses = implementation.get();
}
public static void main(String[] args) {
CityDistrict arrayListImpl = new CityDistrict(ArrayList::new);
CityDistrict linkedListImpl = new CityDistrict(LinkedList::new);
}
}
尽管如此,当您的API用户可以决定在内部使用哪些实现时(尤其是如果它可能会影响某些性能问题),我不确定它是否正常。这打破了封装规则。如果你关心OOP技术(你通常应该做什么),这很重要。
我宁愿提供默认实现(此处ArrayList
是一个不错的选择)并添加通过工厂方法切换到所需实现的功能:
class CityDistrict {
List<House> houses;
private CityDistrict(Supplier<List<House>> supplier) {
houses = supplier.get();
}
public CityDistrict() {
this(ArrayList::new);
}
public CityDistrict with(Supplier<List<House>> implementation) {
return new CityDistrict(implementation);
}
}