享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
享元模式的主要优点是:相同对象只要保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
其主要缺点是: 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。 读取享元模式的外部状态会使得运行时间稍微变长。
在这个例子中{@link alchemishop(药剂商店)}的货架上有大量的药剂。填充
shelves(货架){@link alchemischeshop(药剂商店)}使用{@link PotionFactory(药剂工厂)}(它代表了这个页面中的Flyweight)
示例)。在内部{@link PotionFactory}保存了一个药剂的列表。可以很方便的创建。
public class App { /** * Program entry point. * * @param args command line args */ public static void main(String[] args) { var alchemistShop = new AlchemistShop(); alchemistShop.enumerate(); } } /** * AlchemistShop holds potions on its shelves. It uses PotionFactory to provide the potions. */ public class AlchemistShop { private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class); private final List<Potion> topShelf; private final List<Potion> bottomShelf; /** * Constructor. */ public AlchemistShop() { var factory = new PotionFactory(); topShelf = List.of( factory.createPotion(PotionType.INVISIBILITY), factory.createPotion(PotionType.INVISIBILITY), factory.createPotion(PotionType.STRENGTH), factory.createPotion(PotionType.HEALING), factory.createPotion(PotionType.INVISIBILITY), factory.createPotion(PotionType.STRENGTH), factory.createPotion(PotionType.HEALING), factory.createPotion(PotionType.HEALING) ); bottomShelf = List.of( factory.createPotion(PotionType.POISON), factory.createPotion(PotionType.POISON), factory.createPotion(PotionType.POISON), factory.createPotion(PotionType.HOLY_WATER), factory.createPotion(PotionType.HOLY_WATER) ); } /** * Get a read-only list of all the items on the top shelf. * * @return The top shelf potions */ public final List<Potion> getTopShelf() { return List.copyOf(this.topShelf); } /** * Get a read-only list of all the items on the bottom shelf. * * @return The bottom shelf potions */ public final List<Potion> getBottomShelf() { return List.copyOf(this.bottomShelf); } /** * Enumerate potions. */ public void enumerate() { LOGGER.info("Enumerating top shelf potions(列举顶级药水)\n"); topShelf.forEach(Potion::drink); LOGGER.info("Enumerating bottom shelf potions(列举底层药水)\n"); bottomShelf.forEach(Potion::drink); } } /** * PotionFactory is the Flyweight in this example. It minimizes memory use by sharing object * instances. It holds a map of potion instances and new potions are created only when none of the * type already exists. */ public class PotionFactory { private final Map<PotionType, Potion> potions; public PotionFactory() { potions = new EnumMap<>(PotionType.class); } Potion createPotion(PotionType type) { var potion = potions.get(type); if (potion == null) { switch (type) { case HEALING: potion = new HealingPotion(); potions.put(type, potion); break; case HOLY_WATER: potion = new HolyWaterPotion(); potions.put(type, potion); break; case INVISIBILITY: potion = new InvisibilityPotion(); potions.put(type, potion); break; case POISON: potion = new PoisonPotion(); potions.put(type, potion); break; case STRENGTH: potion = new StrengthPotion(); potions.put(type, potion); break; default: break; } } return potion; } } /** * Interface for Potions. */ public interface Potion { void drink(); } /** * HealingPotion. */ public class HealingPotion implements Potion { private static final Logger LOGGER = LoggerFactory.getLogger(HealingPotion.class); @Override public void drink() { LOGGER.info("You feel healed(你感觉恢复了). (Potion={})", System.identityHashCode(this)); } } /** * HolyWaterPotion. */ public class HolyWaterPotion implements Potion { private static final Logger LOGGER = LoggerFactory.getLogger(HolyWaterPotion.class); @Override public void drink() { LOGGER.info("You feel blessed(你感到神圣庇佑). (Potion={})", System.identityHashCode(this)); } } /** * InvisibilityPotion. */ public class InvisibilityPotion implements Potion { private static final Logger LOGGER = LoggerFactory.getLogger(InvisibilityPotion.class); @Override public void drink() { LOGGER.info("You become invisible(你变得隐形了). (Potion={})", System.identityHashCode(this)); } } /** * PoisonPotion. */ public class PoisonPotion implements Potion { private static final Logger LOGGER = LoggerFactory.getLogger(PoisonPotion.class); @Override public void drink() { LOGGER.info("Urgh! This is poisonous(啊!这是有毒的). (Potion={})", System.identityHashCode(this)); } } /** * StrengthPotion. */ public class StrengthPotion implements Potion { private static final Logger LOGGER = LoggerFactory.getLogger(StrengthPotion.class); @Override public void drink() { LOGGER.info("You feel strong(你感觉很坚强). (Potion={})", System.identityHashCode(this)); } } /** * Enumeration for potion types. */ public enum PotionType { HEALING, INVISIBILITY, STRENGTH, HOLY_WATER, POISON }