享元(Flyweight)模式運用共享技術高效地支持大量細粒度對象的複用。java
當系統中存在大量類似或相同的對象時,有可能會形成內存溢出等問題。享元模式嘗試重用現有的同類對象,若是未找到匹配的對象則建立新對象,從而減小系統中重複建立對象實例的性能和內存消耗。數據庫
享元模式將對象的信息分爲兩個部分:內部狀態(Internal State)和外部狀態(External State)。內部狀態是對象可共享出來的信息,存儲在享元對象內部而且不會隨環境改變而改變。外部狀態是隨環境改變而改變的、不可共享的狀態,必須由客戶端保存,並在享元對象建立後在須要使用時再傳入到享元對象內部。緩存
享元模式包含以下角色:dom
本節經過一個簡單示例,展現享元模式的實現。示例代碼以下:ide
// Flyweight接口 // public interface IShape { void draw(); } // ConcreteFlyweight類 // public class Circle implements IShape { private String color; private int radius; public Circle(String color) { this.color = color; } // 內部狀態color做爲參數傳入構造方法 public void setRadius(int radius) { this.radius = radius; } // 外部狀態radius做爲參數傳入成員方法 @Override public void draw() { System.out.println("Draw a circle[Color: " + color + ", Radius: " + radius + "]"); } } // 享元工廠 // public class ShapeFactory { private static final Map<String, IShape> CIRCLE_POOL = new HashMap<>(); // 享元池單例 public static IShape getCircle(String color) { Circle circle = (Circle) CIRCLE_POOL.get(color); // 先從享元池中查找對象 if (circle == null) { circle = new Circle(color); // 若對象不存在,則建立一個新的Flyweight對象 CIRCLE_POOL.put(color, circle); // 將新建立的Flyweight對象添加到享元池中 System.out.println("###Create a new circle in " + color); } return circle; } } // 驗證代碼 // public class FlyweightDemo { private static final String[] COLORS = {"Red", "Green", "Blue", "White", "Black"}; public static void main(String[] args) { for(int i=0; i < 10; ++i) { Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor()); circle.setRadius(getRandomRadius()); circle.draw(); } } private static String getRandomColor() { return COLORS[(int)(Math.random() * COLORS.length)]; } private static int getRandomRadius() { return (int)(Math.random() * 100); } }
執行結果以下:性能
###Create a new circle in White Draw a circle[Color: White, Radius: 82] Draw a circle[Color: White, Radius: 72] ###Create a new circle in Red Draw a circle[Color: Red, Radius: 76] ###Create a new circle in Blue Draw a circle[Color: Blue, Radius: 11] Draw a circle[Color: Red, Radius: 78] Draw a circle[Color: Blue, Radius: 74] Draw a circle[Color: Red, Radius: 73] Draw a circle[Color: White, Radius: 98] ###Create a new circle in Black Draw a circle[Color: Black, Radius: 96] Draw a circle[Color: Red, Radius: 52]
可見,循環10次實際只建立了四個Circle對象。此外,雖然只有一個紅色(內部狀態)的Circle對象,但它能夠具備不一樣的半徑(外部狀態)。this
享元模式的優勢以下:code
缺點以下:對象