Feature-Oriented Java Development

There's a cool new (?) way of Java development that I've been learning about in the past weeks while not being able to blog. The approach is generically referred to as "capabilities" in the context of NetBeans Platform applications, via the Lookup concept.

Another way to understand the idea is to look at it from the point of view of the problem it tries to solve. Often, you find that you have your data access code embedded within your user interface. For example, within a window you make a call to a database. Instead of that, feature-oriented Java development entails creating an object that provides a collection of your domain, which in the case below is a collection of Trips (e.g., for a trip planner application).

The object is constructed by assigning features to it. Below, you can see features such as SaveableEntityCapability and RemovableEntityCapability. Both of these, as well as the other features below, are interfaces. The interfaces are implemented below, within the collection object, which returns a Lookup, because it implemented Lookup.Provider:

public final class TripCollection implements Lookup.Provider {

    private List trips;
    private Lookup lookup;
    private InstanceContent instanceContent;
    private TripSearchDAO dao = new TripSearchDAO();

    public TripCollection() {
        trips = new ArrayList();
        // Create an InstanceContent to hold abilities...
        instanceContent = new InstanceContent();
        // Create an AbstractLookup to expose InstanceContent contents...
        lookup = new AbstractLookup(instanceContent);
        // Add a "Reloadable" feature to this entity:
        instanceContent.add(new ReloadableEntityCapability() {
            @Override
            public void reload() throws Exception {
                ProgressHandle handle = ProgressHandleFactory.createHandle("Loading...");
                handle.start();
                List result = dao.search();
                for (Trip trip : result) {
                    if (!getTrips().contains(trip)) {
                        getTrips().add(trip);
                    }
                }
                handle.finish();
            }
        });
        // Add a "Saveable" feature to this entity:
        instanceContent.add(new SaveableEntityCapability() {
            @Override
            public void save(Trip trip) throws Exception {
                dao.save(trip);
            }
        });
        // Add a "Creatable" feature to this entity:
        instanceContent.add(new CreatableEntityCapability() {
            @Override
            public void create(Trip trip) throws Exception {
                dao.create(trip);
            }
        });
        // Add a "Removable" feature to this entity:
        instanceContent.add(new RemovableEntityCapability() {
            @Override
            public void remove(Trip trip) throws Exception {
                dao.remove(trip);
                getTrips().remove(trip);
            }
        });
    }

    @Override
    public Lookup getLookup() {
        return lookup;
    }

    public List getTrips() {
        return trips;
    }

}

Now, anywhere in the application, I can get a reference to the collection object above and then use its "getLookup" to query for the presence of a feature and then call the method on the feature, which the implementation will handle for me.

In this way, the user interface developer need only be aware of the names of the features, without needing to care about their implementation.

For the full blown series on this, focusing on a CRUD scenario, see these articles on NetBeans Zone:

Now I'm thinking about redesigning the JFugue Music NotePad around this approach. You'd have a Composition object that returns a Lookup consisting of features. What features, exactly? Well, the JFugue Features page implies that there'll be features with names like "CreatableMusicCapability", "ConvertableFileCapability", "ManipulatablePatternCapability," etc. And the implementations of all these features is going to be centralized within one single Java class, just like the above, which is really neat & convenient, compared to having the implementations of features spread throughout the application.

 

Comments:

I like this approach a lot! This looks like a good way for making the roles of objects explicit in the code. And since a single object can participate in multiple different functional collaborations, this could be used for making explicit how program features are implemented. I think I will take your example and experiment with more "coarse grained" capabilities that correspond not to services provided by individual classes but to functional features of a whole program. I this case, however, I would need to represent whole inter-object-collaborations as individual capabilities. I will let you know if I manage to get something out of this...

Posted by guest on May 14, 2011 at 03:21 AM PDT #

Btw. somehow I think the idea you described could also be used for realizing the goals of the Domain Driven Design. Here, capabilities would form a "conceptual" domain model that contains only methods that make sense in terms of the problem domain. This model would then make its clients independent of how its technical implementation actually looks like.

Posted by Andrzej Olszak on May 14, 2011 at 03:22 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today