All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.puremvc.java.patterns.facade.Facade Maven / Gradle / Ivy

Go to download

PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern. This is the specific implementation for the Java language. It does not support modular programming since it uses Singletons as Core actors rather than the Multiton used in the MultiCore Version.

The newest version!
//
//  PureMVC Java Standard
//
//  Copyright(c) 2019 Saad Shams 
//  Your reuse is governed by the Creative Commons Attribution 3.0 License
//

package org.puremvc.java.patterns.facade;

import org.puremvc.java.core.Controller;
import org.puremvc.java.core.Model;
import org.puremvc.java.core.View;
import org.puremvc.java.interfaces.*;
import org.puremvc.java.patterns.observer.Notification;

import java.util.function.Supplier;

/**
 * 

A base Singleton IFacade implementation.

* *

In PureMVC, the Facade class assumes these * responsibilities:

* *
    *
  • Initializing the Model, View * and Controller Singletons.
  • *
  • Providing all the methods defined by the IModel, * IView, & IController interfaces.
  • *
  • Providing the ability to override the specific Model, * View and Controller Singletons created.
  • *
  • Providing a single point of contact to the application for * registering Commands and notifying Observers
  • *
* *

Example usage:

*
 *  {@code
 *	import org.puremvc.as3.patterns.facade.Facade;
 *
 *	import com.me.myapp.model.*;
 *	import com.me.myapp.view.*;
 *	import com.me.myapp.controller.*;
 *
 *	public class MyFacade extends Facade
 *	{
 *		// Notification constants. The Facade is the ideal
 *		// location for these constants, since any part
 *		// of the application participating in PureMVC
 *		// Observer Notification will know the Facade.
 *		public static final String GO_COMMAND = "go";
 *
 *		// Override Singleton Factory method
 *		public synchronized static IFacade getInstance(Supplier facadeSupplier) {
 *			if(instance == null) instance = facadeSupplier.get();
 *			return instance;
 *		}
 *
 *		// optional initialization hook for Facade
 *		public void initializeFacade() {
 *			super.initializeFacade();
 *			// do any special subclass initialization here
 *		}
 *
 *		// optional initialization hook for Controller
 *		public void initializeController()  {
 *			// call super to use the PureMVC Controller Singleton.
 *			super.initializeController();
 *
 *			// Otherwise, if you're implmenting your own
 *			// IController, then instead do:
 *			// if ( controller != null ) return;
 *			// controller = MyAppController.getInstance(() -> new MyAppController());
 *
 *			// do any special subclass initialization here
 *			// such as registering Commands
 *			registerCommand( GO_COMMAND, () -> new com.me.myapp.controller.GoCommand() )
 *		}
 *
 *		// optional initialization hook for Model
 *		public void initializeModel() {
 *			// call super to use the PureMVC Model Singleton.
 *			super.initializeModel();
 *
 *			// Otherwise, if you're implmenting your own
 *			// IModel, then instead do:
 *			// if ( model != null ) return;
 *			// model = MyAppModel.getInstance(() -> new MyAppModel());
 *
 *			// do any special subclass initialization here
 *			// such as creating and registering Model proxys
 *			// that don't require a facade reference at
 *			// construction time, such as fixed type lists
 *			// that never need to send Notifications.
 *			registerProxy( new USStateNamesProxy() );
 *
 *			// CAREFUL: Can't reference Facade instance in constructor
 *			// of new Proxys from here, since this step is part of
 *			// Facade construction!  Usually, Proxys needing to send
 *			// notifications are registered elsewhere in the app
 *			// for this reason.
 *		}
 *
 *		// optional initialization hook for View
 *		public void initializeView() {
 *			// call super to use the PureMVC View Singleton.
 *			super.initializeView();
 *
 *			// Otherwise, if you're implmenting your own
 *			// IView, then instead do:
 *			// if ( view != null ) return;
 *			// view = MyAppView.getInstance(() -> new MyAppView());
 *
 *			// do any special subclass initialization here
 *			// such as creating and registering Mediators
 *			// that do not need a Facade reference at construction
 *			// time.
 *			registerMediator( new LoginMediator() );
 *
 *			// CAREFUL: Can't reference Facade instance in constructor
 *			// of new Mediators from here, since this is a step
 *			// in Facade construction! Usually, all Mediators need
 *			// receive notifications, and are registered elsewhere in
 *			// the app for this reason.
 *		}
 *	}
 * }
 * 
* * @see Model Model * @see View View * @see Controller Controller * @see org.puremvc.java.patterns.observer.Notification Notification * @see org.puremvc.java.patterns.mediator.Mediator Mediator * @see org.puremvc.java.patterns.proxy.Proxy Proxy * @see org.puremvc.java.patterns.command.SimpleCommand SimpleCommand * @see org.puremvc.java.patterns.command.MacroCommand MacroCommand */ public class Facade implements IFacade { // Private references to Model, View and Controlle protected IController controller; protected IModel model; protected IView view; // The Singleton Facade instance. protected static IFacade instance; // Message Constants protected final String SINGLETON_MSG = "Facade Singleton already constructed!"; /** *

Constructor.

* *

This IFacade implementation is a Singleton, * so you should not call the constructor * directly, but instead call the static Singleton * Factory method Facade.getInstance()

* * @throws Error Error if Singleton instance has already been constructed * */ public Facade() { if(instance != null) throw new Error(SINGLETON_MSG); instance = this; initializeFacade(); } /** *

Initialize the Singleton Facade instance.

* *

Called automatically by the constructor. Override in your * subclass to do any subclass specific initializations. Be * sure to call super.initializeFacade(), though.

*/ protected void initializeFacade() { initializeModel(); initializeController(); initializeView(); } /** *

Facade Singleton Factory method

* * @param facadeSupplier facade Supplier Function * @return the Singleton instance of the Facade */ public synchronized static IFacade getInstance(Supplier facadeSupplier) { if(instance == null) instance = facadeSupplier.get(); return instance; } /** *

Initialize the Controller.

* *

Called by the initializeFacade method. * Override this method in your subclass of Facade * if one or both of the following are true:

* *
    *
  • You wish to initialize a different IController.
  • *
  • You have Commands to register with the Controller at startup.
  • *
* *

If you don't want to initialize a different IController, * call super.initializeController() at the beginning of your * method, then register Commands.

*/ protected void initializeController() { if(controller != null) return; controller = Controller.getInstance(() -> new Controller()); } /** *

Initialize the Model.

* *

Called by the initializeFacade method. * Override this method in your subclass of Facade * if one or both of the following are true:

* *
    *
  • You wish to initialize a different IModel.
  • *
  • You have Proxys to register with the Model that do not * retrieve a reference to the Facade at construction time.
  • *
* *

If you don't want to initialize a different IModel, * call super.initializeModel() at the beginning of your * method, then register Proxys.

* *

Note: This method is rarely overridden; in practice you are more * likely to use a Command to create and register Proxys * with the Model, since Proxys with mutable data will likely * need to send INotifications and thus will likely want to fetch a reference to * the Facade during their construction.

*/ protected void initializeModel() { if(model != null) return; model = Model.getInstance(() -> new Model()); } /** *

Initialize the View.

* *

Called by the initializeFacade method. * Override this method in your subclass of Facade * if one or both of the following are true:

* *
    *
  • You wish to initialize a different IView.
  • *
  • You have Observers to register with the View
  • *
* *

If you don't want to initialize a different IView, * call super.initializeView() at the beginning of your * method, then register IMediator instances.

* *

Note: This method is rarely overridden; in practice you are more * likely to use a Command to create and register Mediators * with the View, since IMediator instances will need to send * INotifications and thus will likely want to fetch a reference * to the Facade during their construction.

*/ protected void initializeView() { if(view != null) return; view = View.getInstance(() -> new View()); } /** *

Register an ICommand with the Controller by Notification name.

* * @param notificationName the name of the INotification to associate the ICommand with * @param commandSupplier a reference to the Supplier Function of the ICommand */ public void registerCommand(String notificationName, Supplier commandSupplier) { controller.registerCommand(notificationName, commandSupplier); } /** *

Remove a previously registered ICommand to INotification mapping from the Controller.

* * @param notificationName the name of the INotification to remove the ICommand mapping for */ public void removeCommand(String notificationName) { controller.removeCommand(notificationName); } /** *

Check if a Command is registered for a given Notification

* * @param notificationName notification name * @return whether a Command is currently registered for the given notificationName. */ public boolean hasCommand(String notificationName) { return controller.hasCommand(notificationName); } /** *

Register an IProxy with the Model by name.

* * @param proxy the IProxy instance to be registered with the Model. */ public void registerProxy(IProxy proxy) { model.registerProxy(proxy); } /** *

Retrieve an IProxy from the Model by name.

* * @param proxyName the name of the proxy to be retrieved. * @return the IProxy instance previously registered with the given proxyName. */ public IProxy retrieveProxy(String proxyName) { return model.retrieveProxy(proxyName); } /** *

Remove an IProxy from the Model by name.

* * @param proxyName the IProxy to remove from the Model. * @return the IProxy that was removed from the Model */ public IProxy removeProxy(String proxyName) { return model.removeProxy(proxyName); } /** *

Check if a Proxy is registered

* * @param proxyName proxy name * @return whether a Proxy is currently registered with the given proxyName. */ public boolean hasProxy(String proxyName) { return model.hasProxy(proxyName); } /** *

Register a IMediator with the View.

* * @param mediator a reference to the IMediator */ public void registerMediator(IMediator mediator) { view.registerMediator(mediator); } /** *

Retrieve an IMediator from the View.

* * @param mediatorName mediator name * @return the IMediator previously registered with the given mediatorName. */ public IMediator retrieveMediator(String mediatorName) { return view.retrieveMediator(mediatorName); } /** *

Remove an IMediator from the View.

* * @param mediatorName name of the IMediator to be removed. * @return the IMediator that was removed from the View */ public IMediator removeMediator(String mediatorName) { return view.removeMediator(mediatorName); } /** *

Check if a Mediator is registered or not

* * @param mediatorName mediator name * @return whether a Mediator is registered with the given mediatorName. */ public boolean hasMediator(String mediatorName) { return view.hasMediator(mediatorName); } /** *

Create and send an INotification.

* *

Keeps us from having to construct new notification * instances in our implementation code.

* * @param notificationName the name of the notiification to send * @param body the body of the notification * @param type the type of the notification */ public void sendNotification(String notificationName, Object body, String type) { notifyObservers(new Notification(notificationName, body, type)); } /** *

Create and send an INotification.

* *

Keeps us from having to construct new notification * instances in our implementation code.

* * @param notificationName the name of the notiification to send * @param body the body of the notification */ public void sendNotification(String notificationName, Object body) { sendNotification(notificationName, body, null); } /** *

Create and send an INotification.

* *

Keeps us from having to construct new notification * instances in our implementation code.

* * @param notificationName the name of the notiification to send */ public void sendNotification(String notificationName) { sendNotification(notificationName, null, null); } /** *

Notify Observers.

* *

This method is left public mostly for backward * compatibility, and to allow you to send custom * notification classes using the facade.

* *

Usually you should just call sendNotification * and pass the parameters, never having to * construct the notification yourself.

* * @param notification the INotification to have the View notify Observers of. */ public void notifyObservers(INotification notification) { view.notifyObservers(notification); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy