Search code examples
javadesign-patternsdesign-principles

What's the best way to have different parent field initialization?


I have a class as below

public abstract class MyObjectManager {
   private final Map<MyKey, MyObject> objects;
   private final MySystem system;
   MyObjectManager(MySystem inputSystem) {
     system = inputSystem;
     // also initialize the "objects" field.
   } 
   public void write(MyKey myKey, MyObject myObject) {...}
   public MyObject read(MyKey myKey) {...}
   public abstract MyObject getNewestObject();
}

I need two types of ConcreteManagers which will have different map implementation, for example,

One uses new LinkedHashMap(CAPACITY_1, LOAD_FACTOR_1, true){ // override the removeEldestEntry(){// logic 1}}.

The other uses new LinkedHashMap(CAPACITY_2, LOAD_FACTOR_2, false){ // override the removeEldestEntry(){// logic 2}}.

I don't want to pass the map as a @param since the map implementation is fixed for each ConcreteManager.

Should I use a strategy pattern or factory pattern to have different map initialization?

Or should I move the objects field to each implementation classes? But their implementation of read and write methods duplicate a lot.


Solution

  • If I understood your question, it seems to me that you could add the map as a parameter the abstract class, then pass the concrete map instance in the children constructor. For example:

    public abstract class MyObjectManager {
    
        private final Map<MyKey, MyObject> objects;
        private final MySystem system;
    
        MyObjectManager(final Map<MyKey, MyObject> objects, MySystem inputSystem) {
            this.objects = objects;
            this.system = inputSystem;
        }
    }
    
    public class ConcreteManager extends MyObjectManager {
        public ConcreteManager(MySystem inputSystem) {
            super(new LinkedHashMap(CAPACITY_1, LOAD_FACTOR_1, true), inputSystem);
        }
    }
    

    This way fulfils your constraints:

    • The Map class is fixed to a concrete manager implementation
    • The objects attribute remains in the parent class