设计模式-享元模式

运用共享技术有效地支持大量的细粒度的对象。

以下场景适用享元模式:

  • 一个应用程序适用了大量的对象。
  • 完全由于使用大量的对象,造成很大的存储开销。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

 30112455a55246b29a6e2197690266551f5.jpg

 

示例1:

public interface BMWCar {

    double calculatePrice(BMWCarCustomisation custom);

    void printFullCharacteristics(BMWCarCustomisation custom);

}

 

public interface BMWCarCustomisation {

    // customize Tire size

    int getTireSize();

    String getLaserSignature();

    // a lot of customisation attributes can be in there for a BMW car

    void printCustomisations();

}

 

public interface BMWCarFactory {

    BMWCar createCar();

}

 

public interface BMWCarFlyWeightFactory {

    enum Model {Serie1, Serie2, Serie3};

    BMWCar getBMWModel(Model m);

}

 

public class BMWSerie1 implements BMWCar {

    private final static double BASE_PRICE = 25000;



    @Override

    public double calculatePrice(BMWCarCustomisation custom) {

        return BASE_PRICE + getSpecificSerie1PriceBasedOnCustom(custom) + getExportationTaxe(custom);

    }



    @Override

    public void printFullCharacteristics(BMWCarCustomisation custom) {

        // print all BMW 1 Series specific characteristics

        // (codes in there)

        custom.printCustomisations(); // print details based on these customisations

    }



    private double getSpecificSerie1PriceBasedOnCustom(BMWCarCustomisation custom) {

        // (e.g., calculation based on custom specific to Series 1)

        double sum = 0;

        if (custom.getTireSize() == 19) {

            sum += 1200;

        } else {

            sum += 2100;

        }

        return sum;

    }



    private double getExportationTaxe(BMWCarCustomisation custom) {

        // (calculation based on custom exportation taxes only for this model)

        double sum = 0;

        if (!custom.getLaserSignature().isEmpty()) {

            sum += 987;

        }

        return sum;

    }

}

 

public class BMWSerie1Factory implements BMWCarFactory {

    @Override

    public BMWCar createCar() {

        return new BMWSerie1();

    }

}

 

public class BMWSerie2 implements BMWCar {

    private final static double BASE_PRICE = 28000;



    @Override

    public double calculatePrice(BMWCarCustomisation custom) {

        return BASE_PRICE + getSpecificSerie2PriceBasedOnCustom(custom);

    }



    @Override

    public void printFullCharacteristics(BMWCarCustomisation custom) {

        // print all BMW 2 Series specific characteristics

        // (codes in there)

        custom.printCustomisations(); // print details based on these customisations

    }



    private double getSpecificSerie2PriceBasedOnCustom(BMWCarCustomisation custom) {

        // (e.g., calculation based on custom specific to Series 2)

        double sum = 0;

        if (custom.getTireSize() == 19) {

            sum += 2000;

        } else {

            sum += 3000;

        }

        if (!custom.getLaserSignature().isEmpty()) {

            if (custom.getLaserSignature().length() > 10) {

                sum += 1200;

            } else {

                sum += 400;

            }

        }

        return sum;

    }

}

 

public class BMWSerie2Factory implements BMWCarFactory {

    @Override

    public BMWCar createCar() {

        return new BMWSerie2();

    }

}

 

public class BMWSerieCarCustomisation implements BMWCarCustomisation  {

    private int tireSize;

    private String laserSignature;



    public BMWSerieCarCustomisation(int tireSize, String laserSignature) {

        this.tireSize = tireSize;

        this.laserSignature = laserSignature;

    }



    public int getTireSize() {

        return tireSize;

    }



    public String getLaserSignature() {

        return laserSignature;

    }



    @Override

    public void printCustomisations() {

        System.out.println("Tire Size:" + getTireSize());

        System.out.println("LaserSignature:" + getLaserSignature());

        System.out.println("LaserSignature Size:" + getLaserSignature().length());

    }

}

 

 

public class BMWSerieFlyWeightFactory implements BMWCarFlyWeightFactory {

    private Map<Model, BMWCar> cache = new HashMap<>();



    public synchronized BMWCar getBMWModel(Model m) {

        if (!cache.containsKey(m)) {

            BMWCarFactory concreteFactory;

            switch (m) {

                case Serie2:

                    concreteFactory = new BMWSerie2Factory();

                    break;

                /*

                case Serie3:

                    concreteFactory = new BMWSerie3Factory();

                    break;

                */

                /*

                 * Just code to have a hint !

                 */

                default:

                    concreteFactory = new BMWSerie1Factory();

                    break;

            }

            cache.put(m, concreteFactory.createCar());

        }

        return cache.get(m);

    }

}

 

public class MainTest {



    public static void main(String[] args) {

        BMWCarFlyWeightFactory factory = new BMWSerieFlyWeightFactory();

        BMWCar serie1Car = factory.getBMWModel(BMWCarFlyWeightFactory.Model.Serie1);

        BMWCar serie1Car2 = factory.getBMWModel(BMWCarFlyWeightFactory.Model.Serie1);

        System.out.println("check for Object for Serie1:" + (serie1Car == serie1Car2));

        BMWCar serie2Car = factory.getBMWModel(BMWCarFlyWeightFactory.Model.Serie2);

        BMWCar serie2Car2 = factory.getBMWModel(BMWCarFlyWeightFactory.Model.Serie2);

        System.out.println("check for Object for Serie2:" + (serie2Car == serie2Car2));

        BMWCarCustomisation custom1 = new BMWSerieCarCustomisation(19, "Oh yeah");

        BMWCarCustomisation custom2 = new BMWSerieCarCustomisation(21, "For bob");

        BMWCarCustomisation custom3 = new BMWSerieCarCustomisation(26, "give it a ride !!");

        // BMW 1 Series

        System.out.println("BMW Serie1 + Custom1 Price:\nFull Price:" + serie1Car.calculatePrice(custom1));

        serie1Car.printFullCharacteristics(custom1);

        System.out.println("BMW Serie1 + Custom2 Price:\nFull Price:" + serie1Car.calculatePrice(custom2));

        serie1Car.printFullCharacteristics(custom2);

        System.out.println("BMW Serie1 + Custom3 Price:\nFull Price:" + serie1Car.calculatePrice(custom3));

        serie1Car.printFullCharacteristics(custom3);

        /// It's the samed BMW 1 Series Flyweight instance; the variant part is provided

        /// by the operation and customs

        // BMW 2 Series

        System.out.println("BMW Serie2 + Custom1 Price:\nFull Price:" + serie2Car.calculatePrice(custom1));

        serie2Car.printFullCharacteristics(custom1);

        System.out.println("BMW Serie2 + Custom2 Price:\nFull Price:" + serie2Car.calculatePrice(custom2));

        serie2Car.printFullCharacteristics(custom2);

        System.out.println("BMW Serie2 + Custom3 Price:\nFull Price:" + serie2Car.calculatePrice(custom3));

        serie2Car.printFullCharacteristics(custom3);

        /// It's the samed BMW 2 Series Flyweight instance; the variant part is provided

        /// by the operation and customs

    }

}

 

示例2:

public interface Potion {



  void drink();

}

 

public class PoisonPotion implements Potion {



  @Override

  public void drink() {

    System.out.println("Urgh! This is poisonous. (Potion="+System.identityHashCode(this)+")" );

  }

}

 

public enum PotionType {



  HEALING, INVISIBILITY, STRENGTH, HOLY_WATER, POISON

}

 

public class HealingPotion implements Potion {



  @Override

  public void drink() {

    System.out.println("You feel healed. (Potion="+System.identityHashCode(this)+")");

  }

}

 

public class HolyWaterPotion implements Potion {



  @Override

  public void drink() {

    System.out.println("You feel blessed. (Potion={"+System.identityHashCode(this)+"})" );

  }

}

 

public class InvisibilityPotion implements Potion {



  @Override

  public void drink() {

    System.out.println("You become invisible. (Potion="+System.identityHashCode(this)+")" );

  }

}

 

public class StrengthPotion implements Potion {



  @Override

  public void drink() {

    System.out.println("You feel strong. (Potion="+System.identityHashCode(this)+")" );

  }

}

 

 

public class PotionFactory {



  private final Map<PotionType, Potion> potions;



  public PotionFactory() {

    potions = new EnumMap<>(PotionType.class);

  }



  Potion createPotion(PotionType type) {

    Potion 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;

  }

}

 

public class AlchemistShop {



  private List<Potion> topShelf;

  private List<Potion> bottomShelf;



  /**

   * Constructor

   */

  public AlchemistShop() {

    topShelf = new ArrayList<>();

    bottomShelf = new ArrayList<>();

    fillShelves();

  }



  private void fillShelves() {



    PotionFactory factory = new PotionFactory();



    topShelf.add(factory.createPotion(PotionType.INVISIBILITY));

    topShelf.add(factory.createPotion(PotionType.INVISIBILITY));

    topShelf.add(factory.createPotion(PotionType.STRENGTH));

    topShelf.add(factory.createPotion(PotionType.HEALING));

    topShelf.add(factory.createPotion(PotionType.INVISIBILITY));

    topShelf.add(factory.createPotion(PotionType.STRENGTH));

    topShelf.add(factory.createPotion(PotionType.HEALING));

    topShelf.add(factory.createPotion(PotionType.HEALING));



    bottomShelf.add(factory.createPotion(PotionType.POISON));

    bottomShelf.add(factory.createPotion(PotionType.POISON));

    bottomShelf.add(factory.createPotion(PotionType.POISON));

    bottomShelf.add(factory.createPotion(PotionType.HOLY_WATER));

    bottomShelf.add(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 Collections.unmodifiableList(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 Collections.unmodifiableList(this.bottomShelf);

  }



  /**

   * Enumerate potions

   */

  public void enumerate() {



    System.out.println("Enumerating top shelf potions");



    for (Potion p : topShelf) {

      p.drink();

    }



    System.out.println("Enumerating bottom shelf potions");



    for (Potion p : bottomShelf) {

      p.drink();

    }

  }

}

 

public class App {



  /**

   * Program entry point

   * 

   * @param args command line args

   */

  public static void main(String[] args) {

    AlchemistShop alchemistShop = new AlchemistShop();

    alchemistShop.enumerate();

  }

}

架构师成长营

转载于:https://my.oschina.net/u/3963977/blog/2985828

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值