design-patternspassive-view

Creating child views in the Passive View pattern


I am very interested in using the Passive View pattern to improve testability, but I am not sure how to call child dialogs.

Do you have the parent view create the child view and return an interface to the parent controller, then have the parent controller create the child controller?


Solution

  • I have been thinking about this a lot and I think I have a couple of possible solutions.

    1. Add a method to the view class to generate the subordinate dialog
    2. Create a factory that generates the model, view. and controller for the subordinate dialog

    Method 1

    class ParentView extends JDialog implements IParentView {
      public IChildView newChildView(...) {
        return new ChildView(...);
      }
      // ...
    }
    
    interface IParentView {
      IChildView newChildView(...);
      // ...
    }
    
    class ParentController {
      private IParentView view;
      public ParentController(IParentView view) {
        this.view  = view;
      }
    
      public void showChildView() {
        IChildView childView = view.newChildView();
        ChildController childController = new ChildController(childView);
        childView.setVisible(true);
      }
    }
    
    class ChildView extends JDialog implements IChildView {
      // ...
    }
    
    interface IChildView {
      void setVisible(boolean visible);
    }
    
    class ChildController {
      private IChildView view;
      public ChildController(IChildView view) {
        this.view = view;
      }
    }
    

    Method 2

    // During testing, create a mock ChildFactory and assign it to instance
    class ChildFactory implements IChildFactory {
        private static IChildFactory instance;
        public static ChildFactory getInstance() {
          if (instance == null) {
            instance = new ChildFactory();
          }
          return instance;
        }
        public static void setInstance(IChildFactory factory) {
          instance = factory;
        }
        public void createChild(IParentView parent) {
          IChildView view = new ChildView(parent);
          ChildController controller = new ChildController(view);
          view.setVisible(true);
        }
    }
    
    interface IChildFactory {
      void createChild(IParentView parent);
    }
    
    class ParentController {
      private IParentView view;
      public ParentController(IParentView view) {
        this.view  = view;
      }
      public void showChildView() {
        ChildFactory.getInstance().createChild(view);
      }
    }
    
    // ParentView class similar to method 1