阅前声明: http://blog.csdn.net/heimaoxiaozi/archive/2007/01/19/1487884.aspx
/****************** Exercise 11 *****************
* Following the form of the example Lunch.java,
* create a class called ConnectionManager that
* manages a fixed array of Connection objects.
* The client programmer must not be able to
* explicitly create Connection objects, but can
* only get them via a static method in
* ConnectionManager. When the ConnectionManager
* runs out of objects, it returns a null
* reference. Test the classes in main().
***********************************************/
import c05.connection.*;
public class E11_ConnectionManager {
public static void main(String args[]) {
Connection c =
ConnectionManager.getConnection();
while(c != null) {
System.out.println(c);
c.doSomething();
c = ConnectionManager.getConnection();
}
}
}
//+M java E11_ConnectionManager
package c05.connection;
public class Connection {
private static int counter = 0;
private int id = counter++;
Connection() {}
public String toString() {
return "Connection " + id;
}
public void doSomething() {}
}
package c05.connection;
public class ConnectionManager {
private static Connection[] pool =
new Connection[10];
private static int counter = 0;
static {
for(int i = 0; i < pool.length; i++)
pool[i] = new Connection();
}
// Very simple -- just hands out each one once:
public static Connection getConnection() {
if(counter < pool.length)
return pool[counter++];
return null;
}
}
**The Connection class uses a static int called counter to automatically give each Connection object an identifier, which it will produce as part of it’s toString( ) representation. Connection also has a doSomething( ) method, which is presumably the useful work that motivates you to use the Connection object.
**Note that the constructor for Connection is “friendly,” so it is unavailable outside of this package. Thus, the client programmer is unable to access that constructor and cannot make instances of Connection directly. The only way to get Connection objects is through the ConnectionManager.
**In the ConnectionManager, a static array of objects is initialized inside the static clause, which is only called once when the class is loaded (you can look up further details on static clauses in the book). In this version of the solution, the connection manager is trivial, since it only produces each Connection object in the array once.
**You might want to create a slightly more sophisticated connection manager by allowing a connection to be checked back in when the client programmer is finished with it. Here’s one way to accomplish this:
// Connections that can be checked in.
import c05.connection2.*;
public class E11_ConnectionManager2 {
public static void main(String args[]) {
Connection[] ca = new Connection[10];
// Use up all the connections
for(int i = 0; i < 10; i++)
ca[i] = ConnectionManager.getConnection();
// Should produce "null" since there are no
// more connections:
System.out.println(
ConnectionManager.getConnection());
// Return connections, then get them out:
for(int i = 0; i < 5; i++) {
ca[i].checkIn();
Connection c =
ConnectionManager.getConnection();
System.out.println(c);
c.doSomething();
c.checkIn();
}
}
}
//+M java E11_ConnectionManager2
package c05.connection2;
public class Connection {
private static int counter = 0;
private int id = counter++;
Connection() {}
public String toString() {
return "Connection " + id;
}
public void doSomething() {}
public void checkIn() {
ConnectionManager.checkIn(this);
}
}
package c05.connection2;
public class ConnectionManager {
private static Connection[] pool =
new Connection[10];
static {
for(int i = 0; i < pool.length; i++)
pool[i] = new Connection();
}
// Produce the first available connection:
public static Connection getConnection() {
for(int i = 0; i < pool.length; i++)
if(pool[i] !=null) {
Connection c = pool[i];
pool[i] = null;// Indicates "in use"
return c;
}
return null; // None left
}
public static void checkIn(Connection c) {
for(int i = 0; i < pool.length; i++)
if(pool[i] ==null) {
pool[i] = c; // Check it back in
return;
}
}
}
**
When a Connection is checked out, its slot in pool is set to null. When the client programmer is done with the connection, checkIn( ) will return it to the connection pool by finding a null slot in pool and assigning it there.**Of course, there are all kinds of problems with this approach. What if a client checks a Connection in and then continues to use it? What if they check it in more than once? The book Thinking in Patterns (available from www.BruceEckel.com) has a more thorough coverage of the problem of the connection pool.