The Java programming language is one of the most taught, learned, written about, and programmed in programming languages today. Beginning its life in 1995, it rode in on the Object-Oriented Programming hype-wave of the nineties. Although some might argue that Java’s primary means of abstraction is the class—and therefore Java is primarily object-oriented, the huge number of available Java libraries indicates otherwise. In this essay, I will argue that Java’s most powerful means of abstraction is the library. I will also explore whether a new term—namely “Library-Oriented Programming”—is warranted to describe programming using libraries as the main abstraction.
A library (in OO languages) is a collection of classes designed and made to be used together in an organized way. There are certain conventions that must be followed to use the library. And within those conventions, you can solve a problem. It may be a foreign concept to some to see libraries described as a form of abstraction, so I might need to borrow the credibility of an outside source. According to FOLDOC, the definition of abstraction is:
A library is meant to hide the details of a particular problem (say reading the contents of c:\directory\file.txt) by generalizing it to some more abstract problem (like creating a File object, then creating a FileInputStream, then wrapping it in an InputStreamReader). In general, though, classes of a library must be used together for them to work. This means that the library is an atomic unit. One could define a programming paradigm as a way to define atomic units (and their interactions) that model a problem in an abstract way. Java, therefore, relies on libraries as one of its means of abstraction.
But are libraries the principal means of abstraction? When you need to read in a weird file format or speak some well-defined protocol, do you ask yourself “I wonder if someone has written a library to do this?” or do you ask yourself “I wonder if someone has written a class to do this?” My intuition is to ask for the library. And I suspect most others do the same.
On the other side, you don’t create an object to solve the problem, you create a framework–another word for a library. On the whole, solitary classes are not powerful enough to abstract away the complexity of real-world problems. Classes make great calculators, cash registers, and rectangle simulators—examples that teachers and books use to teach OOP principles—but they won’t abstract very much more than that before they start to get brittle.
Since many classes are needed, and those classes, in general, are intertwined with the specifics of the library, the classes themselves do not abstract away problems atomically. The meat of the abstraction’s ability to solve a problem is in the whole of the library.
One could argue that, although libraries are very commonly used to model problems, the main source of the power of the libraries is from the object-oriented nature of Java. It is therefore unfair to say that libraries are “principal”, even though they are used as abstractions. Do not the bread and butter of OOP—object encapsulation, message passing, and polymorphism—come into play?
Object-oriented programming was touted as the solution to the code reuse problem. However, experience has shown the programming community that classes, by themselves, are not reused. When was the last time you downloaded a single .class file? It is, in fact, not the objects that are important, but the interactions and relationships between objects that are important. Their interactions are where they get their power. Hence libraries, which define a set of classes and their interactions, are the principal means of code reuse. And it is this reuse, because libraries can solve many specific problems in a general way, that defines their place as principal.
As to whether a new name should be used, well, that’s really not up to me. The community will decide if it needs “library-oriented programming”. I will probably use it—it seems a useful concept. I would say it’s at least as useful as “language-oriented programming” as applied to Lisp. And don’t forget that you heard it here first if others start adopting it.
From day to day, Java programmers write classes and methods. And they write code that instantiates, initializes, and operates on objects. But in the long view, those classes and methods and their patterns of use principally constitute libraries. Libraries have their own means of encapsulation (through interface classes) and their own means of combination (also through the interface classes). Library-oriented programming parallels Lisp’s Language-oriented programming—where programmers write functions and macros then take a step back and realize they have written a whole new language. Could this be one of the reasons Java libraries flourish while Common Lisp’s libraries don’t? On another note: should language designers try to see the long view of their language as they design it? Can a language be built that makes the library the basic form of abstraction? What kind of abstraction would be superimposed on top?
