(11) Composite mode
A composite pattern is a combination of a set of objects, which can be container objects or single objects. Group objects agree to include single objects, and can also include other group objects. Common behaviors are defined for composite objects and single objects. The meaning of the composite mode is to ensure that the client calls the consistency of the single object and the composite object.
class TreeNode{ private String name; private TreeNode parent; private Vector<TreeNode> children = new Vector<TreeNode>(); public TreeNode(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TreeNode getParent() { return parent; } public void setParent(TreeNode parent) { this.parent = parent; } public void setChildren(Vector<TreeNode> children) { this.children = children; } //Add child node public void add(TreeNode node){ children.add(node); } // delete child node public void remove(TreeNode node){ children.remove(node); } // get child node public Enumeration<TreeNode> getChildren(){ return children.elements(); } } public class Composite { TreeNode root = null; public Composite(String name){ root = new TreeNode(name); } public static void main(String[] args){ Composite com = new Composite("A"); TreeNode nodeb = new TreeNode("B"); TreeNode nodec = new TreeNode("C"); nodeb.add(nodec); com.root.add(nodeb); } }(12) Flyweight model
The main purpose of the flyweight pattern is to achieve object sharing and reduce memory overhead when there are a large number of objects in the system. Usually used with the factory pattern.
When a client requests. The factory checks whether there is an available object in the current object pool, and returns an existing object if there is one. Create a new object without it. The database connection pool is the most typical example of using the Flyweight pattern.
public class ConnectionPool implements IConnectionPool{ private DBbean dbBean; //Connection pool configuration properties private boolean isActive = false; //Connection pool active status private int contActive = 0; //Record the total number of connections created private List<Connection> freeConnection = new Vector<Connection>(); private List<Connection> activeConnection = new Vector<>(); private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>(); public ConnectionPool(DBbean dbBean){ super(); this.dbBean = dbBean; init(); cheackPool(); } public void init(){ try { Class.forName (dbBean.getDriverName ()); for(int i = 0;i < dbBean.getInitConnections();i++){ Connection conn; conn = newConnection(); if(conn != null){ freeConnection.add(conn); contActive++; } } isActive = true; } catch (ClassNotFoundException | SQLException e) { e.printStackTrace (); } } // get the current number of connections public Connection getCurrentConnection(){ Connection conn = threadLocal.get(); if(!isValid(conn)){ conn = getConnection(); } return conn; } // get the connection public synchronized Connection getConnection() { Connection conn = null; try { // Infer if the maximum number of connections is exceeded if(contActive < this.dbBean.getMaxActiveConnections()){ if (freeConnection.size() > 0) { conn = freeConnection.get(0); if (conn != null) { threadLocal.set(conn); } freeConnection.remove(0); } else { conn = newConnection(); } }else{ // Continue to get the connection until it is reconnected wait(this.dbBean.getConnTimeOut()); conn = getConnection(); } if (isValid(conn)) { activeConnection.add(conn); contActive ++; } } catch (SQLException e) { e.printStackTrace (); } catch (ClassNotFoundException e) { e.printStackTrace (); } catch (InterruptedException e) { e.printStackTrace (); } return conn; } // get new connection private synchronized Connection newConnection() throws ClassNotFoundException, SQLException { Connection conn = null; if (dbBean != null) { Class.forName (dbBean.getDriverName ()); conn = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword()); } return conn; } // release the connection public synchronized void releaseConn(Connection conn) throws SQLException { if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) { freeConnection.add(conn); activeConnection.remove(conn); contActive --; threadLocal.remove(); // Wake up all waiting threads to grab the connection notifyAll(); } } // Infer whether the connection is available private boolean isValid(Connection conn) { try { if (conn == null || conn.isClosed()) { return false; } } catch (SQLException e) { e.printStackTrace (); } return true; } // destroy the connection pool public synchronized void destroy() { for (Connection conn : freeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace (); } } for (Connection conn : activeConnection) { try { if (isValid(conn)) { conn.close(); } } catch (SQLException e) { e.printStackTrace (); } } isActive = false; contActive = 0; } // connection pool status @Override public boolean isActive() { return isActive; } // Regularly check the connection pool status @Override public void cheackPool() { if(dbBean.isCheakPool()){ new Timer().schedule(new TimerTask() { @Override public void run() { // 1. The connection status in the thread // 2. The minimum and maximum number of connections in the connection pool // 3. Check other states. Since there are still several thread management classes that need to be written here, it will not be added temporarily. System.out.println("Number of empty line pool connections: "+freeConnection.size()); System.out.println("Number of active connections::"+activeConnection.size()); System.out.println("Total number of connections: "+contActive); } },dbBean.getLazyCheck(),dbBean.getPeriodCheck()); } } }