Controller Part 2 - Implement ServicesJ8 Home « Controller Part 2 - Implement Services
In this lesson we complete our controller code by implementing the Services
interface. The Services
interface will provide local access to and interaction with the Manufacturer file from a local client.
Implement ServicesTop
In this part of the lesson we implement the services
interface, thus providing local access to and interaction with the Manufacturer file from a local client. The implementation acts as
a service layer between the Manufacturer GUI and the business methods of the StockImpl
class. This class is a singleton and is the only object that interacts with the StockImpl
singleton and therefore the only direct user of the locking/unlocking therein. This is the controller element of the MVC paradigm.
Creating The ServicesImpl
Class Top
We will call our implementation class ServicesImpl
and this class will implement the Services
interface. For the stocking, unstocking and search functionality requested by the stakeholder Stocking Goods Limited we will delegate functionality of these business methods to the StockImpl
class. We will also have to include a method that calls our private constructor to ensure via double locking that we only ever have one Services
instance. Lastly we will have to include a method that gets a local file handle for the StockImpl
class.
Create the ServicesImpl
class in the services
package and cut and paste the following code into it.
package services;
import java.rmi.RemoteException;
import java.util.logging.*;
import client.ManufacturerTableModel;
import client.RunMode;
import model.*;
import remoteservices.RemoteServicesImpl;
/**
* This class acts as a service layer between the Manufacturer GUI and the business
* methods of the StockImpl class. This class is a singleton and is the only object
* that interacts with the StockImpl singleton and therefore the only direct user of
* the locking/unlocking therein. This is the controller element of the MVC paradigm.
*
* @author Charlie
* @version 1.0
*
*/
public class ServicesImpl implements Services {
/**
* The Logger instance through which all log messages from this class are routed.
* Logger namespace is J8CaseStudy
.
*/
private static Logger log = Logger.getLogger("J8CaseStudy"); // Log output
/**
* Only create ServicesImpl Singleton first time through using double-checked
* locking to ensure private constructor is only synchronised once.
*/
private volatile static Services uniqueServicesImplInstance;
/**
* Holds a reference to the connection type.
*/
private static StockImpl stockImpl;
private static Services services;
/**
* ServicesImpl Constructor constructor.
*
* @param services The Data handle.
*
*/
private ServicesImpl(Services services) {
log.entering("ServicesImpl", "ServicesImpl", new Object[]{services});
ServicesImpl.services = services;
log.exiting("ServicesImpl", "ServicesImpl");
}
/**
* Clients of the ServicesImpl class have to call this method to get the unique
* instance (singleton) for this class as the constructor is private.
*
* @param runMode The mode the contractor application was started in.
* @param fileHandle A handle to our Manufacturer file
* @param port The port number (used in server mode)
*
* @return The client singleton for ServicesImpl class.
*
* @throws ServicesException Indicates there was a problem accessing the data.
*/
public static Services getServicesImplInstance(RunMode runMode,
String fileHandle, String port) {
log.entering("ServicesImpl", "getServicesImplInstance",
new Object[]{runMode, fileHandle, port});
if (uniqueServicesImplInstance == null) {
synchronized (ServicesImpl.class) {
if (uniqueServicesImplInstance == null) {
if (runMode == RunMode.NON_NETWORK_CLIENT) {
stockImpl = getServices(fileHandle);
uniqueServicesImplInstance = new ServicesImpl(services);
} else {
try {
return RemoteServicesImpl.getServices(
fileHandle, port, runMode);
} catch (RemoteException e) {
throw new ServicesException(e);
}
}
}
}
}
log.exiting("ServicesImpl", "getServicesImplInstance");
return uniqueServicesImplInstance;
}
/**
* Delegate stocking to the StockImpl class.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
* @param stockOrdered The amount of stock order.
*
* @throws StockingException Indicates stocking already done by another user.
* @throws ServicesException Indicates there was a problem accessing the data.
*/
@Override
public void stockFromManufacturer(String name, String location,
int stockLevel, int stockOrdered) throws ServicesException, StockingException {
log.entering("ServicesImpl", "stockFromManufacturer",
new Object[]{name, location, stockLevel, stockOrdered});
// Lock, update and unlock in a single method call
stockImpl.stocking(name, location, stockLevel, stockOrdered);
log.exiting("ServicesImpl", "stockFromManufacturer");
}
/**
* Delegate unstocking to the StockImpl class.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
* @param stockOrdered The amount of unstocking to do.
*
* @throws ServicesException Indicates there was a problem accessing the stockImpl.
*/
@Override
public void unstockBackToManufacturer(String name, String location,
int stockOrdered) throws ServicesException {
log.entering("ServicesImpl", "unstockBackToManufacturer",
new Object[]{name, location, stockOrdered});
// Lock, update and unlock in a single method call
stockImpl.unstocking(name, location, stockOrdered);
log.exiting("ServicesImpl", "unstockBackToManufacturer");
}
/**
* Delegate search to the StockImpl class.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
*
* @return A ManufacturerTableModel containing all Manufacturer records pertaining to
* search criteria.
*
* @throws ServicesException Indicates there was a problem accessing the stockImpl.
*/
@Override
public ManufacturerTableModel searchManufacturers(String name, String location)
throws ServicesException {
log.entering("ServicesImpl", "searchManufacturers",
new Object[]{name, location});
try {
log.exiting("ServicesImpl", "searchManufacturers");
return stockImpl.search(name, location);
} catch (ServicesException e) {
throw new ServicesException(e);
}
}
/**
* Method that gets a StockImpl handle, StockImpl
is a local object.
*
* @param stockImpl The StockImpl
local object.
*
* @return A StockImpl
instance.
* @throws ServicesException Indicates there was a problem accessing the stockImpl.
*
* For more information, see {@link StockImpl}.
*/
public static StockImpl getServices(String stockImpl)
throws ServicesException {
try {
return model.StockImpl.getStockImplInstance(stockImpl);
}
catch (ManufacturerFileAccessException e) {
throw new ServicesException(e);
}
}
}
The following screenshot shows the services
package structure after adding the ServicesImpl
class.
Lesson 14 Complete
In this lesson we coded the services Controller elements of the MVC pattern for our case study.
Related Java Tutorials
Fundamentals - Primitive Variables
Fundamentals - if
Construct
Objects & Classes - Arrays
Objects & Classes - Class Structure and Syntax
Objects & Classes - Reference Variables
Objects & Classes - Methods
Objects & Classes - Instance Variables & Scope
Objects & Classes - Constructors
Objects & Classes - Static Members
Objects & Classes - Enumerations
OO Concepts - Encapsulation
OO Concepts - Inheritance Concepts - Using the super
keyword
Swing - RMI - Serialization
Exceptions - Handling Exceptions
API Contents - Inheritance - Using the package
keyword
API Contents - Inheritance - Using the import
keyword
Concurrency - Synchronization - Synchronized Blocks
What's Next?
In the next section we finish coding the View elements of the MVC pattern for our case study.