Search code examples
javamodel-view-controllerdependency-injectionrefactoringdependency-inversion

How should this class be modified in order to follow the DIP (Dependency Injection Principle)?


How I can modify this class to follow DIP (Dependency Inversion Principle) in order to remove the two ArrayList dependencies in the constructor? How should the interfaces be?

One thing that confuses me is that the new references points to an ArrayList<type> not just the constructor of a class. And I don't know how to handle that situation...

package mvc.controllers;

import java.util.ArrayList;
import mvc.models.AbstractModel;
import mvc.views.AbstractViewPanel;

public abstract class AbstractController {

    private ArrayList<AbstractViewPanel> registeredViews;
    private ArrayList<AbstractModel> registeredModels;

    public AbstractController() {
        registeredViews = new ArrayList<AbstractViewPanel>();
        registeredModels = new ArrayList<AbstractModel>();
    }

    public void addModel(AbstractModel model) {
        registeredModels.add(model);
        model.addPropertyChangeListener(this);
    }

    public void removeModel(AbstractModel model) {
        registeredModels.remove(model);
        model.removePropertyChangeListener(this);
    }

    public void addView(AbstractViewPanel view) {
        registeredViews.add(view);
    }

    public void removeView(AbstractViewPanel view) {
        registeredViews.remove(view);
    }
    ...
}

Solution

  • To do it in Dependency Inversion -way, you could do one of the following:

    1. Dependencies to the lists are given in the constructor:

      public abstract class AbstractController {
      
      private List<AbstractViewPanel> registeredViews;
      private List<AbstractModel> registeredModels;
      
      public AbstractController(List<AbstractViewPanel> registeredViews, List<AbstractModel> registeredModels) {
          this.registeredViews = registeredViews;
          this.registeredModels = registeredModels;
      }
      
    2. Add mutators (setters) for the lists:

      public abstract class AbstractController {
      
      private List<AbstractViewPanel> registeredViews;
      private List<AbstractModel> registeredModels;
      
      public AbstractController() {
      }
      
      public void setRegisteredViews(List<AbstractViewPanel> views) {
         this.registeredViews = views;
      }
      
      public void setRegisteredModels(List<AbstractModel> models) {
         this.registeredModels = models;
      }
      

    Btw, I changed the ArrayLists to Lists. There's no need to introduce a dependency on the List implementation.