Understanding Java Packages and Factories

I read Bruce Eckel Thinking in Java and thereโ€™s an exercise that I just donโ€™t get:

Pg. 161: Exercise 8: (4) After the Lunch.java sample form, create a class called ConnectionManager that manages a fixed array of Connection objects. The client programmer should not explicitly create connection objects , but can only get them through the static method in ConnectionManager. When the ConnectionManager runs out of objects, it returns a null reference. Check the classes in main ().

I came up with the following solution:

// TestConnection.java
import java.util.*;

public class TestConnections {
    public static void main( String[] args ) {
        Connection cn = Connection.makeConnection();

        for (int i = 0; i != 6; ++i) {
            Connection tmp = ConnectionManager.newConnectiton();
            if ( tmp == null )
                System.out.println("Out of Connection objects");
            else {
                System.out.println("Got object: " + tmp );
            }
        }
    }
}

And the second file in the same directory means that everything ends in the same package by default:

// ConnectionManager.java
class Connection { 
    private Connection() {}

    static Connection makeConnection() {
        return new Connection();
    }
}

public class ConnectionManager {
    static private Connection[] _connections = new Connection[5];

    private ConnectionManager() {}

    static public Connection newConnectiton() {
        for ( int i = 0; i != _connections.length; ++i ) {
            if ( _connections[i] == null ) {
                _connections[i] = Connection.makeConnection();
                return _connections[i];
            }
        }
        return null;
    }
}

, Connection Connection.makeConnection factory, , -, . ConnectionManager.java , , , Connection.

, - , , .

Lunch.java, :

//: access/Lunch.java
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:

class Soup1 {
  private Soup1() {}
  // (1) Allow creation via static method:
  public static Soup1 makeSoup() {
    return new Soup1();
  }
}

class Soup2 {
  private Soup2() {}
  // (2) Create a static object and return a reference
  // upon request.(The "Singleton" pattern):
  private static Soup2 ps1 = new Soup2();
  public static Soup2 access() {
    return ps1;
  }
  public void f() {}
}

// Only one public class allowed per file:
public class Lunch {
  void testPrivate() {
    // Can't do this! Private constructor:
    //! Soup1 soup = new Soup1();
  }
  void testStatic() {
    Soup1 soup = Soup1.makeSoup();
  }
  void testSingleton() {
    Soup2.access().f();
  }
} ///:~
+3
7

Lunch.java , . , / interfaces.

// File cm.Connection.java
package cm;

public class Connection {
    // The constructor has package access and so is available to 
    // ConnectionManager, but not to any class outside package cm
    Connection() { }
}

// File cm.ConnectionManager.java
package cm;

public class ConnectionManager {
    static private Connection[] _connections = new Connection[5];

    private ConnectionManager() {}

    static public Connection newConnectiton() {
        for ( int i = 0; i != _connections.length; ++i ) {
            if ( _connections[i] == null ) {
                _connections[i] = new Connection();
                return _connections[i];
            }
        }
        return null;
    }
}

, Connection ConnectionManager cm.

// File different.TestConnections.java
package different;

import cm.*;

public class TestConnections {

    public static void main(String[] args) {
        Connection conn = ConnectionManager.newConnectiton();
    }
}

: TestConnections different.

+1

. Connection (.. ). , ConnectionManager Connection; . factory.

, , , , Connection, ConnectionManager; newConnection , , , (, ).

+4

: , . (ConnectionImpl) .

ConnectionManager .

( ):

public interface Connection() {
}

public class ConnectionManager {
  private static class ConnectionImpl implement Connection {
    private ConnectionImpl() {
    }
  }
  public static Connection createConnection() {
    return new ConnectionImpl();
  }
}
+3

- Connection ConnectionManager. . Andreas_D Donal .

public class ConnectionManager {
    private static Connection[] _connections = new Connection[5];

    private ConnectionManager() {}

    public static Connection newConnectiton() {
        for ( int i = 0; i != _connections.length; ++i ) {
            if ( _connections[i] == null ) {
                _connections[i] = new Connection();
                return _connections[i];
            }
        }
        return null;
    }

    public static class Connection { 
        private Connection() {}
    }

}

, , TestConnections,

public class TestConnections {

    public static void main(String[] args) {
        Connection conn = ConnectionManager.newConnectiton();
    }
}
+2

, Connection.makeConnection factory

, , .

,

-

. , "newConnection" "getConnection" - .

, , . ( ).

0

ConnectionManager , . unit test.

0

makeConnection() , , . ( Connection, , ).

Note that client programmers can work around this by putting their code in the same pacakge; but code visibility should usually be seen as an aid in helping client programmers see the API, not implementation details, and not as a way to prevent deliberate stupidity or malice. Although, if you really need to run untrusted code, you can prevent code from entering your packages by signing your JARs.

0
source

Source: https://habr.com/ru/post/1773795/


All Articles