12) Flyweight Pattern
类别:
Structural Pattern
问题/动机:
假若绿色是相同部分,占用1M内存 ,如果提取出来,众对象共享其内容,只占1M内存 ,否则占10M ,且随着对象增多,占用越来越多内存 ,无疑是浪费资源
A flyweight is an object that minimizes memory usage by sharing as much data as possible with other similar objects (通过共享来削减内存)
方案:
示例:
import java.util.List; import java.util.Map; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; public class FlyweightPatternDemo { public static void main(final String[] args) { CoffeeShop shop = new CoffeeShop(); shop.takeOrder("Cappuccino", 2); shop.takeOrder("Latte", 1); shop.takeOrder("Macchiato", 1); shop.takeOrder("Latte", 4); shop.takeOrder("Cappuccino", 5); shop.takeOrder("Latte", 3); shop.takeOrder("Macchiato", 3); shop.takeOrder("Cappuccino", 3); shop.takeOrder("Macchiato", 5); shop.takeOrder("Latte", 5); shop.takeOrder("Cappuccino", 3); shop.takeOrder("Macchiato", 5); shop.service(); System.out.println(shop.report()); } } // Instances of CoffeeFlavour will be the Flyweights class Coffee { private final String name; Coffee(final String name) { this.name = name; } @Override public String toString() { return name; } } // Menu acts as a factory and cache for CoffeeFlavour flyweight objects class Menu { private Map<String, Coffee> coffeeMap = new ConcurrentHashMap<String, Coffee>(); synchronized Coffee lookup(final String name) { if (!coffeeMap.containsKey(name)) coffeeMap.put(name, new Coffee(name)); return coffeeMap.get(name); } synchronized int totalCoffeeMade() { return coffeeMap.size(); } } // Order is the context of the CoffeeFlavour flyweight. class Order { private final int tableNumber; private final Coffee coffee; Order(final int tableNumber, final Coffee coffee) { this.tableNumber = tableNumber; this.coffee = coffee; } void serve() { System.out.println("Serving " + coffee + " to table " + tableNumber); } } class CoffeeShop { private final List<Order> orders = new Vector<Order>(); private final Menu menu = new Menu(); void takeOrder(final String name, final int table) { Coffee coffee = menu.lookup(name); Order order = new Order(table, coffee); orders.add(order); } void service() { for (Order order : orders) order.serve(); } String report() { return "\ntotal coffee objects made: " + menu.totalCoffeeMade(); } }
Serving Cappuccino to table 2 Serving Latte to table 1 Serving Macchiato to table 1 Serving Latte to table 4 Serving Cappuccino to table 5 Serving Latte to table 3 Serving Macchiato to table 3 Serving Cappuccino to table 3 Serving Macchiato to table 5 Serving Latte to table 5 Serving Cappuccino to table 3 Serving Macchiato to table 5 total coffee objects made: 3
应用:
不足:(
优化:)