|
When introduced to CORBA and the advantages that it can bring to
programs, two different reactions are common. The first common
reaction is to dismiss it altogether as a buzzword or a
bloat-producing phenomenon. This objection can be valid. CORBA can be
misused to produced bloated software. CORBA definitely is not the
silver bullet that will reduce software development and maintainance
time to zero. The problem with this view is that it invalidates all
the benefits of CORBA—its network transparency, programming language
independence, and standardization.
On the other hand are those who take up the CORBA cause as if it were
the end to all means. Some software projects have taken to exposing
the C++ string classes via CORBA. This view is equally dangerous,
because it is bound to make unnecessary demands on resources, and
stands to add a fair amount of bloat and slowdown to the application
for no good reason.
How, then, should a developer approach CORBA use in the small to
medium size programs that are common in the free software world, what
are the mistakes that CORBA utilizers sometimes make, and how can
CORBA be used effectively in applications?
Possible Steps to Determining an Application CORBA Interface
-
Determine Usefulness to Others.
Your nethack client may be the most wonderful program on the face of
the earth, but unless it implements functionality that many other
applications can make use of, then you probably do not need to
"CORBAize" it.
Coordination with other applications is a common reason for creating a
CORBA interface to a program. The GNOME panel exports its ability to
hold applets via the GNOME::Panel CORBA
interface, and similarly, each applet allows the panel to talk
to it via the GNOME::Applet interface.
Another common reason for creating a CORBA interface to a program is
to allow control from scripts. Nethack players may very well want to
be able to write perl scripts that
-
Write it out.
Once you understand what interface you want your application to offer
to the world, codify its data types and operations into an IDL file.
-
Genericize.
Look at the set of operations and data types just defined, and see if
any of them are specific to your implementation. If they are, try to
rework the interface so that it could comfortably be implemented by
other programs of the same genre. Also try to split functionality
Take this example of a possible interface to a text editor:
interface MyEditor {
typedef long FileID;
FileID open_file(in string filename);
void close_file(in FileID fid);
void save_file(in FileID fid);
};
|
This interface has no editor-specific functionality; it could just as
well be called the ``FileManipulator'' interface and be used by a
spreadsheet.
-
Normalize.
Often people will create an interface that contains implicit
objects. In the above ``MyEditor'' example, the ``FileID'' data type
is acting as an object handle, even though it is just an integer.
Given this information, we could rework the ``MyEditor'' interface to
come up with the following IDL:
interface ManipulatedFile {
void close();
void save();
};
interface FileManipulator {
ManipulatedFile
open_file(in string filename);
ManipulatedFile new_file();
};
|
This process may be viewed as similar to the process of normalizing
relational databases.
Optimize.
Have others review your design. Use your knowledge of how CORBA is
implemented, your good judgment as a software developer, and the
information below to improve on your original design. Look at the
existing GNOME CORBA interfaces, and see if using one of them would be
more advantageous.
Common CORBA Mistakes
Confusing CORBA with program-local object systems. A useful analogy here would be ``Store strings inside string objects
provided by the programming languages. Consider allowing access to
catalogues of guitar strings via CORBA objects.'' For single-language
objects that do not hold data that specifically needs to be accessed
from other programs, CORBA object servers hold no advantage over
traditional object implementations in shared libraries. For data that
of and by itself can be useful to other programs, CORBA object servers
are a good way of making this availability happen.
Confusion implementing with sub-classing. The common method of providing a new implementation of a given
programming language object is to subclass that object and write new
routines to override the inherited operation implementations. CORBA
inheritance is for interfaces only.
Sub-classing an object just to denote a new implementation makes for a
confusing class hierarchy. It also introduces the possible problem of
handling implementation-specific extensions, which counteract the
whole idea of having a generic interface.
Providing a new implementation of an existing interface does not
require inheritance on the CORBA level. The flip side of this, of
course, is that implementation inheritance in CORBA is not
standardized, normally requiring the object implementor to re-implement
all the operations on an object.
Confusing CORBA operation invocations with function calls. They look like normal function calls. They act like normal function
calls. Beware! They often are much slower than normal function
calls. If you find your application doing a tight loop with a CORBA
operation on data elements, instead try modeling your data structures
so that one operation invocation can process all the data. Remember,
it can take as long to perform thousand loop iterations of a local
function call as it can to perform a single operation invocation on a
remote object.
Utilizing CORBA Effectively
Keep interface exposition at a high level. Not only does exposing low-level interfaces cause increased dependence
upon the internal organization of a software system, but it also means
you have to put more code into exporting your interfaces, introducing
the risk for more bugs and increasing bloat.
Take advantage of the ``object by value'' concept. The basic premise of the ``object by value'' concept is to transport
the data to the program where it is needed and perform data
manipulations there. For example, instead of a spreadsheet client
making repeated calls on a remote spreadsheet object to have it change
the colors of cells, the object-by-value approach would be for the
client to request all relevant spreadsheet data in an agreed-upon
format (such as XML), manipulate that data, and send it back to the
spreadsheet object server. The CORBA 2.3 specification includes a
built-in ``value'' type to make using OBV much easier.
Use 'oneway' operations if you can. This is one of the few tips that can greatly increase the speed of
some CORBA operation invocations without any real cost. For CORBA
operations that do not return any values and do not raise any
exceptions, specifying the 'oneway' keyword in the IDL declaration
will mean the ORB will not have to await a reply from the remote end
before returning control to the calling program. Given the high
latency of network links (relative to that of a intra-process function
call), 'oneway' operations can increase speed dramatically in a good
ORB.
Mix other IPC mechanisms as appropriate. CORBA is not the ultimate IPC mechanism. For programs that need to
share large amounts of data efficiently, shared memory systems
(system-local or network-wide) can be much more efficient. Real-time
synchronization can often better be accomplished via semaphores and
message queues. A good example is the GNU Image Manipulation Program,
which controls plug-ins via pipes, but shares the actual image data via
shared memory. (In the future the GIMP may switch to using CORBA for
plug-in control, but image data will still be exported via shared
memory).
|