الگوی مگس وزن

تاریخچه

بنابر کتاب Gang Of Four، الگوی مگس وزن برای اولین بار توسط پائل کادلر و مارک لینتون در سال ۱۹۹۰ برای یک ویرایشگر متنی به‌طور مفصل بررسی شد، با وجود این که شبیه همین تکنیک در سال‌های قبل در سیستم‌های دیگر نیز استفاده شده بود به‌طور مثال در فریم‌ورک Weinand .

تغییر ناپذیری( Immutability ) و برابری ( Equality )

برای اینکه در بین ریسمان‌های مختلف اجرایی برنامه ناسازگاری به وجود نیاید اشیا مگس وزن بایستی در طول اجرای برنامه تغییرناپذیر باشند.
و همچنین بایستی هر دو شئ مگس وزنی که مقدار یکسانی داشته باشند از نظر برنامه‌نویسی برابر ( Equal ) محسوب شوند.

برای درک بیشتر این موضوع به مثال #C زیر توجه کنید ( به تابع Equals و GetHashCode و == و =! دقت کنید)
public class CoffeeFlavour {
    private readonly string _flavour;

    public CoffeeFlavour(string flavour) {
        _flavour = flavour;
    }

    public string Flavour {
        get { return _flavour; }
    }

    public override bool Equals(object obj) {
        if (ReferenceEquals(null, obj)) return false;
        return obj is CoffeeFlavour && Equals((CoffeeFlavour)obj);
    }

    public bool Equals(CoffeeFlavour other) {
        return string.Equals(_flavour, other._flavour);
    }

    public override int GetHashCode() {
        return (_flavour != null ? _flavour.GetHashCode() : 0);
    }

    public static bool operator ==(CoffeeFlavour a, CoffeeFlavour b) {
        return Equals(a, b);
    }

    public static bool operator !=(CoffeeFlavour a, CoffeeFlavour b) {
        return !Equals(a, b);
    }}

مثال در جاوا

import java.util.concurrent.CopyOnWriteArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;// Instances of CoffeeFlavour will be the Flyweightsclass CoffeeFlavour {
  private final String name;

  CoffeeFlavour(String newFlavor) {
    this.name = newFlavor;
  }

  @Override
  public String toString() {
    return name;
  }}// Menu acts as a factory and cache for CoffeeFlavour flyweight objectsclass Menu {
  private Map<String, CoffeeFlavour> flavours = new HashMap<String, CoffeeFlavour>();

  CoffeeFlavour lookup(String flavorName) {
    if (!flavours.containsKey(flavorName))
      flavours.put(flavorName, new CoffeeFlavour(flavorName));
    return flavours.get(flavorName);
  }

  int totalCoffeeFlavoursMade() {
    return flavours.size();
  }}class Order {
  private final int tableNumber;
  private final CoffeeFlavour flavour;

  Order(int tableNumber, CoffeeFlavour flavor) {
    this.tableNumber = tableNumber;
    this.flavour = flavor;
  }

  void serve() {
    System.out.println("Serving " + flavour + " to table " + tableNumber);
  }}public class CoffeeShop {
  private final List<Order> orders = new CopyOnWriteArrayList<Order>();
  private final Menu menu = new Menu();

  void takeOrder(String flavourName, int table) {
    CoffeeFlavour flavour = menu.lookup(flavourName);
    Order order = new Order(table, flavour);
    orders.add(order);
  }

  void service() {
    for (Order order : orders) {
      order.serve();
      orders.remove(order);
    }
  }

  String report() {
    return "\ntotal CoffeeFlavour objects made: "
        + menu.totalCoffeeFlavoursMade();
  }

  public static void main(String[] args) {
    CoffeeShop shop = new CoffeeShop();

    shop.takeOrder("Cappuccino", 2);
    shop.takeOrder("Frappe", 1);
    shop.takeOrder("Espresso", 1);
    shop.takeOrder("Frappe", 897);
    shop.takeOrder("Cappuccino", 97);
    shop.takeOrder("Frappe", 3);
    shop.takeOrder("Espresso", 3);
    shop.takeOrder("Cappuccino", 3);
    shop.takeOrder("Espresso", 96);
    shop.takeOrder("Frappe", 552);
    shop.takeOrder("Cappuccino", 121);
    shop.takeOrder("Espresso", 121);

    shop.service();
    System.out.println(shop.report());
  }}