Tell the class to create a member variable type

Suppose I have a class CityDistrict

like this:

class CityDistrict {
    List<House> houses;
    ...
}

      

Suppose for some usecases is ArrayList

better for houses

and sometimes for LinkedList

. How would you tell CityDistrict to create that class that it should use forhouses

My three ideas:

1) Is this truncation for parametric classes? Something like

class CityDistrict<T> {
    T<House> houses;
    ...
}

      

Then you can create CityDistrict<ArrayList>

. But I suppose the information that T should be of type List

is lost here.

2) Or you could create multiple constructors or static factory methods like generateArrayListCityDistrict

, but that's kind of ugly I think.

3) Use some kind of flag in the constructor CityDistrict(int ListFlag)

and match 1

with ArrayList

and so on. Also kind of ugly I guess.

Am I missing the obvious here? What would be a clean and OOP way to handle this situation?

+3


source to share


1 answer


You can pass Supplier<List<House>>

to the constructor. It will decide which implementation 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);
    }

}

      

Although, I'm not sure if it's okay for the API user to decide what implementation should be used internally (especially if it might affect some performance issues). This violates the encapsulation rules a little. And it's important if you care about OOP techniques (which you should usually do).



I would rather provide a default implementation (a ArrayList

good choice here) and add the ability to switch to the desired implementation using a 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);
    }

}

      

+7


source







All Articles