Pular para o conteúdo

Conheça Walt Disney World

Flyweight pattern

Flyweight UML class diagram.svg

In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the flyweight objects temporarily when they are used.

A classic example usage of the flyweight pattern is the data structures for graphical representation of characters in a word processor. It might be desirable to have, for each character in a document, a glyph object containing its font outline, font metrics, and other formatting data, but this would amount to hundreds or thousands of bytes for each character. Instead, for every character there might be a reference to a flyweight glyph object shared by every instance of the same character in the document; only the position of each character (in the document and/or the page) would need to be stored internally.

In other contexts the idea of sharing identical data structures is called hash consing.

Contents

History

According to a textbook Design Patterns: Elements of Reusable Object-Oriented Software,[1] the flyweight pattern was first coined and extensively explored by Paul Calder and Mark Linton in 1990[2] to efficiently handle glyph information in a WYSIWYG document editor, although similar techniques were already used in other systems, e.g., an application framework by Weinand et al. (1988).[3]

Example in Java

// Flyweight object interface
public interface CoffeeOrder {
    public void serveCoffee(CoffeeOrderContext context);
}
 
// ConcreteFlyweight object that creates ConcreteFlyweight 
public class CoffeeFlavor implements CoffeeOrder {
    private String flavor;
 
    public CoffeeFlavor(String newFlavor) {
        this.flavor = newFlavor;
    }
 
    public String getFlavor() {
        return this.flavor;
    }
 
    public void serveCoffee(CoffeeOrderContext context) {
        System.out.println("Serving Coffee flavor " + flavor + " to table number " + context.getTable());
    }
}
 
public class CoffeeOrderContext {
   private int tableNumber;
 
   public CoffeeOrderContext(int tableNumber) {
       this.tableNumber = tableNumber;
   }
 
   public int getTable() {
       return this.tableNumber;
   }
}
 
import java.util.HashMap;
import java.util.Map;
 
//FlyweightFactory object
public class CoffeeFlavorFactory {
    private Map<String, CoffeeFlavor> flavors = new HashMap<String, CoffeeFlavor>();
 
    public CoffeeFlavor getCoffeeFlavor(String flavorName) {
        CoffeeFlavor flavor = flavors.get(flavorName);
        if (flavor == null) {
            flavor = new CoffeeFlavor(flavorName);
            flavors.put(flavorName, flavor);
        }
        return flavor;
    }
 
    public int getTotalCoffeeFlavorsMade() {
        return flavors.size();
    }
}
 
public class TestFlyweight {
   /** The flavors ordered. */
   private static CoffeeFlavor[] flavors = new CoffeeFlavor[100];
   /** The tables for the orders. */
   private static CoffeeOrderContext[] tables = new CoffeeOrderContext[100];
   private static int ordersMade = 0;
   private static CoffeeFlavorFactory flavorFactory;
 
   public static void takeOrders(String flavorIn, int table) {
       flavors[ordersMade] = flavorFactory.getCoffeeFlavor(flavorIn);
       tables[ordersMade++] = new CoffeeOrderContext(table);
   }
 
   public static void main(String[] args) {
       flavorFactory = new CoffeeFlavorFactory();
 
       takeOrders("Cappuccino", 2);
       takeOrders("Cappuccino", 2);
       takeOrders("Frappe", 1);
       takeOrders("Frappe", 1);
       takeOrders("Xpresso", 1);
       takeOrders("Frappe", 897);
       takeOrders("Cappuccino", 97);
       takeOrders("Cappuccino", 97);
       takeOrders("Frappe", 3);
       takeOrders("Xpresso", 3);
       takeOrders("Cappuccino", 3);
       takeOrders("Xpresso", 96);
       takeOrders("Frappe", 552);
       takeOrders("Cappuccino", 121);
       takeOrders("Xpresso", 121);
 
       for (int i = 0; i < ordersMade; ++i) {
           flavors[i].serveCoffee(tables[i]);
       }
       System.out.println(" ");
       System.out.println("total CoffeeFlavor objects made: " +  flavorFactory.getTotalCoffeeFlavorsMade());
   }
}

See also

Multiton

References

  1. ^ *Gamma, Erich; Richard Helm, Ralph Johnson, and John Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. pp. 205–206. ISBN 0-201-63361-2. 
  2. ^ Calder, Paul R.; Linton, Mark A. (October 1990). "Glyphs: Flyweight Objects for User Interfaces". The 3rd Annual ACM SIGGRAPH Symposium on User Interface Software and Technology. Snowbird, Utah, United States. pp. 92-101. doi:10.1145/97924.97935. ISBN 0-89791-410-4. 
  3. ^ Weinand, Andre; Gamma, Erich; Marty, Rudolf (1988). "ET++—an object oriented application framework in C++". OOPSLA (Object-Oriented Programming Systems, Languages and Applications). San Diego, California, United States. pp. 46-57. doi:10.1145/62083.62089. ISBN 0-89791-284-5. 

External links

Personal tools
  • Create account
  • Log in
Namespaces

Variants
Actions
Navigation
Toolbox
Print/export