Providing Callbacks via Interfaces

Problem

You want to provide callbacks ; that is, have unrelated classes call back into your code.

Solution

One way is to use a Java interface.

Discussion

An interface is a class-like object that can contain only abstract methods and final fields. As we’ve seen, interfaces are used a lot in Java! In the standard API, the following are a few of the commonly used interfaces:

  • Runnable, Comparable, and Cloneable (in java.lang)

  • List, Set, Map, and Enumeration/Iterator (in the Collections API; see Chapter 7)

  • ActionListener, WindowListener, and others (in the AWT GUI; see Section 13.5)

  • Driver, Connection, Statement, and ResultSet (in JDBC; see Section 20.4)

  • The "remote interface” -- the contact between the client and the server -- is specified as an Interface (in RMI, CORBA, and EJB)

Suppose we are generating a futuristic building management system. To be energy-efficient, we want to be able to remotely turn off (at night and on weekends) such things as room lights and computer monitors, which use a lot of energy. Assume we have some kind of “remote control” technology: it could be a commercial version of BSR’s house-light control technology “X10”; it could be BlueTooth or 802.11; it doesn’t matter. What matters is that we have to be very careful what we turn off. It would cause great ire if we turned off computer processors automatically -- people often leave things running overnight. It would be a matter of public safety if we ever turned off the building emergency lighting.[23] So we’ve come up with the design shown in Figure 8-1.

Classes for a building management system

Figure 8-1. Classes for a building management system

The code for these classes is not shown (it’s pretty trivial) but it’s in the online source. The top-level classes -- those with names ending in Asset, and BuildingLight -- are abstract classes. You can’t instantiate them, as they don’t have any specific functionality. To ensure -- both at compile time and at runtime -- that we can never switch off the emergency lighting, we need only ensure that the class representing it, EmergencyLight, does not implement the PowerSwitchable interface.

Note that we can’t very well use direct inheritance here. There is no common ancestor class that includes both ComputerMonitor and RoomLights that doesn’t also include ComputerCPU and EmergencyLight. Use interfaces to define functionality in unrelated classes.

How we use these is demonstrated by the BuildingManagement class; this class is not part of the hierarchy shown in Figure 8-1, but instead uses a collection (actually an array, to make the code simpler for illustrative purposes) of Asset objects from that hierarchy.

Items that can’t be switched must nonetheless be in the database, for various purposes (auditing, insurance, and so on). In the method that turns things off, the code is careful to check whether each object in the database is an instance of the PowerSwitchable interface. If so, the object is casted to PowerSwitchable so that its powerDown( ) method can be called. If not, the object is skipped, thus preventing any possibility of turning out the emergency lights or shutting off a machine that is busy running Seti@Home or a big Napster download. Or system backups.

/**
 * BuildingManagement - control an energy-saving building.
 * This class shows how we might control the objects in an office
 * that can safely be powered off at nighttime to save energy - lots of
 * it, when applied to a large office!
 */
public class BuildingManagement {

    Asset things[] = new Asset[24];    
    int numItems = 0;

    /** goodNight is called from a timer Thread at 2200, or when we
     * get the "shutdown" command from the security guard.
     */
    public void goodNight(  ) {
        for (int i=0; i<things.length; i++)
            if (things[i] instanceof PowerSwitchable)
                ((PowerSwitchable)things[i]).powerDown(  );
    }

    // goodMorning() would be the same, but call each one's powerUp(  ).

    /** Add a Asset to this building */
    public void add(Asset thing) {    
        System.out.println("Adding " + thing);
        things[numItems++] = thing;
    }

    /** The main program */
    public static void main(String[] av) {
        BuildingManagement b1 = new BuildingManagement(  );
        b1.add(new RoomLights(101));    // control lights in room 101
        b1.add(new EmergencyLight(101));    // and emerg. lights.
        // add the computer on desk#4 in room 101
        b1.add(new ComputerCPU(10104));
        // and its monitor
        b1.add(new ComputerMonitor(10104));

        // time passes, and the sun sets...
        b1.goodNight(  );
    }
}

When you run this program, it shows all the items being added, but only the PowerSwitchable ones being switched off:

> java BuildingManagement
Adding RoomLights@2dc77f32
Adding EmergencyLight@2e3b7f32
Adding ComputerCPU@2e637f32
Adding ComputerMonitor@2f1f7f32
Dousing lights in room 101
Dousing monitor at desk 10104
>


[23] Of course these lights wouldn’t have remote power-off. But the computers might, for maintenance purposes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.200.71