Java – tells class members the type of variables at creation time
Suppose I have a citydistrict class, as follows:
class CityDistrict { List<House> houses; ... }
Suppose that for some use cases, ArrayList is more suitable for houses, and sometimes even LinkedList How do you tell citydistrict to create classes that it should use for houses
My three ideas are:
1) Is this a use case for parameter classes? It's like
class CityDistrict<T> { T<House> houses; ... }
Then, you can create citydistrict < ArrayList > But I think t should be a list. The information is lost here
2) Or you can create several constructors or static factory methods, such as generatearraylistcitydistrict, but I think it's a little ugly
3) Use some flag variable in the constructor citydistrict (int listflag), Map 1 to ArrayList, and so on I think it's a little ugly
Did I miss the obvious? What is the clean and OOP way to deal with this situation?
Solution
You can pass the vendor < list < house > > to the constructor It will determine the implementation that the instance should use:
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); } }
However, when your API users can decide which implementations to use internally (especially when it may affect some performance problems), I'm not sure it works This breaks the encapsulation rule This is important if you are concerned about OOP technology (what should normally be done)
I prefer to provide the default implementation (ArrayList here is a good choice) and add the ability to switch to the required implementation through the factory method:
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); } }