OO and Java FAQ

Joseph Bergin
Pace University
jbergin@pace.edu
http://csis.pace.edu/~bergin

 

General Questions

1. What is a good place to learn about Object-Oriented Design.

Two good sources are the CRC Card Book (Bellin...) and Designing Object Oriented Software (Wirfs-Brock...). Another book is Hunt's Java for Practitioners, though this focuses more on programming than design. There are many more resources on my web pages. Note that although the techniques are different the quality criteria are the same in OO as in structured design: cohesion, encapsulation, loose binding, thin interfaces...

2. What are design patterns?

Design patterns are a tool for capturing expertise about design and for improving design. For an introduction to patterns look at http://www.enteract.com/~bradapp/docs/patterns-intro.html You can also use the Wiki Web: http://c2.com/cgi/wiki Look especially for their find page. The wiki is the virtual meeting place of the patterns community, actually. It will have information about many aspects of this course including Extreme Programming.

3. What is Extreme Programming (XP)?

Extreme Programming (or XP) is a simple (lightweight) methodology for teams of up to about 10 members on projects of up to about 100 person years. It differs radically from most others. Another similar one is called Scrum. Look on wiki. There is a good intro at http://c2.com/cgi/wiki?ExtremeProgramming. See the book Extreme Programming Explained by Kent Beck. There is also a site devoted to XP http://www.xprogramming.com/ It has a lot of information including an introduction to XP. Note that XP focuses on the implementation part though, not the design part so it is for later in the course. Scrum Methodology is discussed at http://c2.com/cgi/wiki?ScrumMethodology and on their home site: http://www.controlchaos.com/

4. How important is reuse in designing for OO?

OO programmers/designers are learning that reuse is overrated. A much more powerful benefit of OO is the the fact that it enables piecemeal growth. Build a small system that works and then add to it to get a big system. This is the XP way, actually. It has been said that no LARGE project has ever been succesful if built in one go. All successful LARGE projects grew out of well designed small projects. There is a LOT of evidence for this in the telecom industry in which they depend on hundreds of millions of lines of code. This is why Star Wars and its replacements cannot be successful. They are huge and there is no way to build them incrementally. The wiki has this page: http://c2.com/cgi/wiki?PiecemealGrowth

Suppose you are building a large (for you) project. First build a small part of your project that is still "end to end," meaning it has all essential features. Then add features to it. You will then always have something to show even if you come to the end of the schedule before you come to the end of the project.

However, you should always reuse available resources, like the Java libraries.

Client Server and Distributed Computing

1. What is a good place to learn about Client/Server and Distributed Computing?

You can start with: Java Distributed Programming," Jim Farley, O'Reilly & Associates, 1998. My home page has a few resources. The wiki has this: http://c2.com/cgi/wiki?DistributedComputing

2. Does my communication topology need to be a star (centered at the server) or can it be more general?

It can be more general. In RMI, for example it is relatively easy to use a generalized interconnection topology. In effect, each remote object is both a client and a server. An RMI application looks like one large application and hides the fact that it is distributed. If you have a reference to an object local or remote you can send it messages in the same way. It doesn't matter where it is. If each "client" has a list of references to all the other "clients" It could talk to each of them directly and wouldn't have to relay communication thru a server (in RMI)

However, if your application needs a database to store information persistently, a star topology may be the most useful since all communication goes through the server which can capture it for the database. Otherwise you may need too much redundancy to be sure information isn't lost.

3. How do I handle "messages" coming from the client to the server that need to be distributed to all the clients?

The term "message" can mean two things. First is the message protocol of any OO system (send a message to an object ). Second is a distributed/telecom concept (send some information from one place (usually the client) to another (usually the server)). Here we are talking about the second kind.

I have a chat room on my site that does this distribution. A chatroom works something like the following, and requires that the communication be thread safe (synchronized). A client sends a message to the server which catches the resulting "message" using a separate thread. One thread per client. This thread is responsible only for receiving information from the client.

When the message is received, it is passed using sync'd communication to a broadcaster object in the server, which queues the incoming messages from the many threads. All these threads are on the server. The broadcaster is in its own thread also. The broadcaster then sends the incoming messages from the queue to all clients.

The code is available, along with a more complete description at http://csis.pace.edu/~bergin/xp/SampleXPProject.html. The interesting stuff is in the server.

4. How do we implement the message Queue in the above scheme?

You can use a LinkedList from java.util for this. It needs to be sync'd to work in a multi-threaded environment, however. There is a class in java.util called Collections that has a syncing "wrapper" for linked lists and other collections. Don't confuse Collection (root of the collection hierarchy) with Collections (lots of utility code for working with Collection objects.

In my chat code, the queue is much simpler. It is just a single cell with sync'd access. If it is full and some thread wants to insert into it, the thread blocks until it becomes empty. This is probably sufficient for communication (slow) coming from humans unless there are thousands of them (like at Amazon.com).

5. How do I test both Server and client on same machine with ot without Kawa?

If you want to test on one machine you can run the server from the command line (outside Kawa). If the machine in your URL that creates the socket is "localhost" or "127.0.0.1" then the server and client are on the same machine. You can build the program with two projects (one for server and one for client) or you can combine them into one. Kava really doesn't care. The easy way to know what command to use to run the server program from the command line is to run the program from inside Kawa. Kawa puts the command in the output window at the bottom. You can copy this command to a new batch file (server.bat) you run from your working directory. Once your server is running you can then run the client from within Kawa. You may need to experiment with port numbers as you may find that the one you want is in use. Both the server and the client must use the same port number, of course.

RMI chooses its own port numbers by default. This is why it runs afoul of firewalls. You can now tell it what port to use for RMI and thus have your firewall administrator open the needed port.

6. Can we use sockets in Applets? Doesn't the security manager prevent this?

You can create a socket that connects back to the machine from which the applet was loaded, but to no other machine.

GUI Programming

1. Should I use Swing or can I use AWT?

Use what works. AWT is easier, but Swing has a nice design. Use AWT if you need to deploy Applets, however, as Swing isn't well supported yet by browsers. For deployed applications, either will do. However, use one or the other. Don't try to mix them. That may not work correctly.

2. How do I get a Button inside a Panel in my GUI? Do I need inner classes for this?

Actually you don't need inner classes for this. Distinguish between inner classes which is a programming concept and containment of GUI elements which is a human factors design concept. A panel is a Java Component that can contain other Components. The design pattern is called Composite. You send the add message to the Panel giving the button as param. Where it shows up depends on the layout manager of the panel and the form of the add message.

Inner classes on the other hand both control name spaces and provide a handy way to interlink tightly related objects. An object of a (non-static) inner class has an automatic hidden link (reference) to a specific outer class object. This is what makes inner classes so nice for listeners. The listener has a link to the GUI it was created within as well as to the button or whatever it is listening to. The link to the button is done explicitly (addActionListener...). The other is implicit.

3. Should I use the Event pattern "Component Listens to Itself" primarily?
    (See http://csis.pace.edu/~bergin/patterns/event.html)

No. You can use it, but it has a down side. One Component per Listener is much more flexible. Component Listens to Itself is implemented by subclassing the component and also implementing one of the listener interfaces. This binds two kinds of code together that should usually not be bound.

One of the objections made to Component listens to itself is that the gui (display) and the actions performed on the "model" should be separate. Read the stuff on model-view-controller for a look at what the separation should be. Your application minus any gui is the model. The look and feel of the screen (gui) is one or more models. And the listeners are the controllers (MVC). All separate.

If two components need to behave in exactly the same way (as a "business rule") then they can/should share a listener. The pattern is "Say it Once". If Listeners can be parametrized so that a set of components can be created to work with the same Class of listeners then you don't need as many listener classes as you need active components, but you need as many listener objects, generally. An example is in a calculator where a NumberButtonListener class can be used to listen to the 10 digit buttons. But you create 10 Listener objects from this class so that you don't have one object doing testing to determine which button it is handling an event for.

4. Where can I find simple descriptions of how to build GUI code?

See the tutorial on GUI programming at: http://csis.pace.edu/~bergin/sol/java/gui/

Java

1. In Java is there any advantage of declaring and initialising objects at the same time?

Yes, you can't forget to initialize if you do it as part of declaration. Much safer and definitely preferred. Do it the other way only when necessary.

2. What is the difference between overloading and overriding?

Overloading is having two methods (or variables, actually) with the same name but different parameter types in the same class (different "signatures"). Overriding is having a method in a subclass with the identical signature of a method in its superclass. The distinction is important and can lead you into trouble if you don't get it right.

An often confused and important example is the equals method, inherited from Object. If you are building a new class, say Customer, and you build in a method to check equality of Customer objects, giving it the signature

boolean equals(Customer c);

is an overload. This is because the inherited method has signature

boolean equals(Object o);

If you overload equals you will have two different equals methods in your class. However, the compiler and libraries know about the inherited one and call it from a number of places--the HashMap add method, for example. You have to realize that these calls will still go to the inherited method and not to the overloaded one. If you want to write a method to check equality of objects rather than depend on the default behavior of the inherited equals method (reference equality), then you need to override equals, NOT overload it.

This will likely result in your needing a cast within the new (override) version.

Note that you can't overload a method by changing only its return type. You need to change one or more of the input parameters.

3. Why do I have to cast the results of Iterator next function calls (for example)? How is casting handled?

An Iterator's next method is declared in the Iterator interface to return Object. However, when you apply it to a real container object you always have something more specific than Object in the container. But the strong typing of Java says that all the compiler knows only is what is in the declaration of the method--namely Object. Therefore, the compiler forces you to know what you have and to cast.

In general if the left side of an assignment is a specific type (subtype) and the right side is a general type (supertype), then casting is required. Likewise when you send a message to an object, but the object is referred to by a variable more general than its specific type, you will need to cast to the specific type if the method (of the message) isn't in the interface of the general type.

When you cast in Java, the compiler doesn't know if you have done it correctly and letting an incorrect cast go is a disaster (safety and security) so it builds in a run time check that the cast is correct. If it isn't you get a ClassCastException.

Java also provides a means (not very OO, however) to ask an object what its type is so that you can cast it correctly. This is the instanceof operator in Java (and RTTI in C++). However, every use of instanceof is a failure to use polymorphism.

In C++ you can use templates to define a typed collection. Thus, the compiler can enforce typing rules. Therefore, C++ templates let you do some of this at compile time, which is more efficient (compile once -- run many). However, C++ templates don't support (easy) heterogeneous collections as Java does.

4. Can your code inquire whether a class supports a particular interface?

Yes, interfaces and classes are alike with respect to the instanceof operator. Again every use of instanceof is a failure to use polymorphism.

5. How important is coding style when writing Java programs?

Very important. If you don't use a good and consistent style you won't be able to understand, update, or maintain your program. The worst thing you can do is have the attitude that "I'll get it working first and then clean it up later." You won't and you won't. See my coding patterns for a good style at: http://csis.pace.edu/~bergin/patterns/codingpatterns.html

6. How imporant is efficiency when writing Java programs?

Not at all, with one exception. When you choose a basic algorithm choose one with appropriate efficiency. Code with care, but don't worry about low level efficiency. A good compiler can do more to affect efficiency than you can anyway. If you want advice from experts see: http://c2.com/cgi/wiki?PrematureOptimization

7. I'm a novice in Java and expecially OO. What is a great book to start with?

Get Java for Practitioners by John Hunt. It is published by Springer. ISBN 1-85233-093-7. The book has a solid intro to OO thinking in the beginning, plus good material on Java.

Kawa

1. I'm using Kawa. How to I set it up?

See the setup page at http://csis.pace.edu/~wolf/java/kawa/kawa_intro.htm

2. How do I create a jar file in Kawa?

First create a manifest file named MANIFEST.MF

The contents of the file should look like this:

Manifest-Version: 1.0
Main-Class: jwiki.JWiki
Created-By: CodeWarrior Java Linker

In the second line of the above, replace jwiki.JWiki with the name of your main class, prefixed with any package that it is in. In this example the package is jwiki and the main class is JWiki. Note that it is case sensitive. The contents of the Created-By clause can be most anything I'd guess.

Under the Build menu of Kawa, select Make Jar... In the dialog select the third checkbox (Include Manifest File) and browse to the file you included above using the field below.

Click the next checkbox (Specify archive file name) and select a file name in the field below.

In the Content area select either a directory containing your class files or add files (or both) until you have all of the needed class files.

Click the last check box (Save Jar Options in File) and select a filename in the field below. This will save the contents of this box so that you can do the same thing later if your project changes and you want to reubild the jar file. In that case you just open the file you create here.

Click SAVE to save your dialog box parameters.

Click Jar to create and save the jar file.

You can then run your program with something like

java -jar filename.jar

where you replace "filename" with the name you gave your jar file above.

NOTE that if you have a jar file without a proper manifest, then the command to use it is different. In the above case we would need to say

java -cp filename.jar jwiki.JWiki

instead. Note especially that the option chages from -jar to -cp. Thus, the manifest make it easier to use.

 


 

Last Updated: September 29, 2001