Java设计模式(十五)—— 享元模式

        享元模式定义如下:运用共享技术有效地支持大量细粒度的对象。

        享元模式使用共享对象技术,用来尽可能的减少内存使用量,适合用于当大量对象只是重复,因而导致无法令人接受的、使用大量内存的情况。通常对象中的部分状态是可以共享的,常见做法是把他们放在外部数据结构,当需要使用时再将它们传递给享元。

适合享元模式的情景如下:

  • 对大量对象而言,许多属性都是相同的,一旦创建则不能修改
  • 对象的多数状态都可变为外部状态

享元模式各种角色描述:

  •  抽象享元角色(IFlyweight):此角色是所有具体享元的超类,为这些类规定出需要实现的公共接口(或抽象类)方法。
  • 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所定义的接口方法。如果有内部状态的话,必须负责为内部状态提供存储空间。享元对象的内部状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。
  • 享元工厂(FlyweightFactory):本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。

        假设我们正在编制一个学生信息管理类,学生的基本属性包括:学号、姓名、年龄、所在大学、所在市、以及邮编等信息。前三个属性与个体有关,后三个属性一般来说属于共性信息,即对一所具体大学的所有学生而言,后三个属性的值是不变的。 

利用享元模式编写学生信息基本类:

(1)定义抽象享元角色 IFlyweight

对于每个学生信息而言,城市 大学 省份是共享信息,因此定义了获得这三个信息的抽象方法。

public interface IFlyweight {
    String getUniversity();
    String getCity();
    String getProvince();
}

(2)具体享元类Flyweight

通过构造方法Flyweight() 创建了享元对象,并重写了三个 get方法。

public class Flyweight implements IFlyweight{
    private String university;
    private String city;
    private String province;

    public Flyweight(String university, String city, String province) {
        this.university = university;
        this.city = city;
        this.province = province;
    }

    @Override
    public String getUniversity() {
        return university;
    }

    @Override
    public String getCity() {
        return city;
    }

    @Override
    public String getProvince() {
        return province;
    }
}

(3)享元工厂类 FlywightFactory

该类采用了单例模式,成员变量容器map定义了“键-享元对象”的映射。addFlyweight() 方法用于向map容器中添加享元对象;getFlyWeight() 方法从map中获取享元对象。

public class FlyweightFactory {
    private FlyweightFactory(){}
    private static FlyweightFactory factory = new FlyweightFactory();
    private Map map = new HashMap<>();

    //单例模式 完全同步方式
    public synchronized static FlyweightFactory getInstance(){
        return factory;
    }
    public void addFlyweight(String key, IFlyweight fly) {
        map.put(key,fly);
    }
    public synchronized IFlyweight getFlyWeight(String key) {
        IFlyweight obj = map.get(key);
        return obj;
    }
}

(4)学生基本信息类StudInfo

name age是个体变量,flyweight是共享变量

public class StudInfo {
    private String name;
    private int age;
    private IFlyweight flyweight;
    
    public StudInfo(String n, int a, IFlyweight f) {
        name = n;
        age = a;
        flyweight = f;
    }
    public void display() {
        System.out.println("name="+name);
        System.out.println("age="+age);
        System.out.println("university="+flyweight.getUniversity());
        System.out.println("city="+flyweight.getCity());
        System.out.println("province="+flyweight.getProvince());
    }
}

(5)测试类

初始时享元工厂factory是空的,将所需要的享元对象fly,fly2添加到享元工厂中。在建立学生对象前,要先从享元工厂中获取所需的享元对象,之后才能建立学生对象。

public class Test {
    public static void main(String[] args) {
        //工厂实例
        FlyweightFactory factory = FlyweightFactory.getInstance();
        //定义两个享元对象
        IFlyweight flyweight = new Flyweight("长安大学","西安","陕西");
        IFlyweight flyweight2 = new Flyweight("山西医科大学","太原","山西");
        //添加到享元工厂中
        factory.addFlyweight("one", flyweight);
        factory.addFlyweight("two", flyweight2);

        //从享元工厂中获得享元对象
        IFlyweight obj = null;
        obj = factory.getFlyWeight("one");
        IFlyweight obj2 = null;
        obj2 = factory.getFlyWeight("two");
        StudInfo student = new StudInfo("zhangyin",25,obj);
        StudInfo student2 = new StudInfo("minmin",22,obj2);

        student.display();
        System.out.println("==========================================");
        student2.display();
    }
}

输出:

name=zhangyin
age=25
university=长安大学
city=西安
province=陕西
==========================================
name=minmin
age=22
university=山西医科大学
city=太原
province=山西

你可能感兴趣的:(设计模式,java,设计模式,享元模式)