zoukankan      html  css  js  c++  java
  • 《TIJ4》访问权限控制 练习 E08 拓展:创建一个更复杂的ConnectionManager

    题目

    创建一个名为ConnectionManager的类,该类管理一个元素为Connection对象的固定数组。客户端程序员不能直接创建Connection对象,而只能通过ConnectionManager的某个static方法获取它们。当ConnectinManager不再有对象时,它会返回null引用,要允许客户端程序员使用完Connection之后归还它。在main()中检测这些类。

    我的解答

    刚开始是没有思路的,在参考了答案之后,自己默写出来的代码如下。

    package access;
    
    import access.connection2.my.Connection;
    import access.connection2.my.ConnectionManager;
    
    public class E08_ConnectionManager2_My {
    
        public static void main(String[] args) {
            System.out.println("Get 5 connections.");
            Connection[] connections = new Connection[5];
            for (int i = 0; i < connections.length; i++) {
                connections[i] = ConnectionManager.getConnection();
                System.out.println(connections[i].toString());
            }
            System.out.println("Check in 2 connections");
            System.out.println("Check in " + connections[1].toString());
            connections[1].checkIn();
            System.out.println("Check in " + connections[4].toString());
            connections[4].checkIn();
            System.out.println("Get remaining connections.");
            Connection[] remainingConnections = new Connection[7];
            for (int i = 0; i < remainingConnections.length; i++) {
                remainingConnections[i] = ConnectionManager.getConnection();
                System.out.println(remainingConnections[i].toString());
            }
        }
    }
    
    /* Output:
    Get 5 connections.
    Connection 0
    Connection 1
    Connection 2
    Connection 3
    Connection 4
    Check in 2 connections
    Check in Connection 1
    Check in Connection 4
    Get remaining connections.
    Connection 1
    Connection 4
    Connection 5
    Connection 6
    Connection 7
    Connection 8
    Connection 9
    */
    
    package access.connection2.my;
    
    public class Connection {
    
        private static int counter = 0;
        private int id = counter++;
    
        Connection(){}
    
        @Override
        public String toString() {
            return "Connection " + id;
        }
    
        public void doSomething(){
            //Todo
        }
    
        public void checkIn(){
            ConnectionManager.checkIn(this);
        }
    }
    
    package access.connection2.my;
    
    public class ConnectionManager {
    
        private static Connection[] pool = new Connection[10];
    
        static {
            for (int i = 0; i < pool.length; i++) {
                pool[i] = new Connection();
            }
        }
    
        public static Connection getConnection() {
            for (int i = 0; i < pool.length; i++) {
                if (pool[i] != null) {
                    Connection c = pool[i];
                    pool[i] = null; //表示被取出
                    return c;
                }
            }
            return null;    //都被取出
        }
    
        public static void checkIn(Connection c) {
            for (int i = 0; i < pool.length; i++) {
                if (pool[i] == null) {
                    pool[i] = c;
                    return;
                }
            }
        }
    }
    
    

    而参考答案代码如下:

    package access;
    
    import access.connection2.bruce.Connection;
    import access.connection2.bruce.ConnectionManager;
    
    public class E08_ConnectionManager2_Bruce {
        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();
            }
        }
    }
    
    /* Output:
    null
    Connection 0
    Connection 0
    Connection 0
    Connection 0
    Connection 0
    */
    
    
    package access.connection2.bruce;
    
    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 access.connection2.bruce;
    
    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;
                }
            }
        }
    }
    
    

    容易犯错的地方:

    1. private int id = counter++; 由于counter是static变量,因此,所有类的对象共享1个counter,而每个对象生成时,成员变量id要初始化,这句代码依次做了两件事:一、id被初始化为0, 1, 2, 3, ... 。二、counter自增1。
    2. Connection(){} 这里显示声明了构造方法,而访问权限是默认的包访问权限,只有同一个包下的类能调用,对于客户端程序员是不可用的。
    3. private static Connection[] pool = new Connection[10]; 要注意new Connection[10]与new Connection()的区别,这里在初始化pool时只是初始化了空的引用,而每个引用并不指向实际的对象。
    4. 注意学习作者测试方法main()的思路,先取出所有connection, 然后依次归还5个的connection,分别是Connection 0, Connection 1, Connection 2, Connection 3, Connection 4,在每次归还后都要再取一个可用的Connection,第一次归还的是Connection 0,取出的也是Connection 0, 使用之后再次把Connection 0 归还,因此第二趟循环,归还的是Connection 1,在取时由于pool[0]的位置是可以取Connection的,所以取出的依旧是Connection 0;
  • 相关阅读:
    sql server 2005的分页函数ROW_NUMBER
    Silverlight 皮肤(主题)动态切换
    Silverlight 地图导航
    WPF模板概述(数据模板)
    Silverlight MVVM Prism WCF RIA项目框架
    多线程通中的AutoResetEvent与ManualResetEvent
    Silverlight 图形报表 线形图 柱形图 饼图
    WPF 重要新概念读书笔记(转)
    Net基本概念和原理
    数据库辅助工具SqlDbx
  • 原文地址:https://www.cnblogs.com/mrbourne/p/8567794.html
Copyright © 2011-2022 走看看