享元模式:相同的对象只保存一份,降低了因为大幅创建相同对象来对系统的额外开销
享元模式分为4个角色,非享元对象,抽象享元角色,具体享元角色,享元工厂。非享元角色是享元角色的一个参数,如果需要经常需要调用非享元对象,可能会创建很多的享元角色,这时候可以从享元工厂里获取具体的享元角色,使用一个map存放对象,如果对象已经存在直接返回,不存在就创建
非享元对象
public class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(String name) { this.name = name; } }
抽象享元角色
interface Animal { void eat(Person person); }
具体享元角色
public class Dog implements Animal { private String name; public Dog(String name) { this.name = name; } @Override public void eat(Person person) { System.out.println(person.getName()+"在喂小狗吃东西"); } }
享元工厂
public class AnimalFactory { private HashMap<String,Animal> animals =new HashMap<>(); public Animal getAnimal(String name){ Animal animal = animals.get(name); if(animal!=null){ System.out.println("此享元对象已经存在,直接获取"); }else{ animal = new Dog(name); animals.put(name,animal); } return animal; } }
测试类
public class Client { public static void main(String[] args) { AnimalFactory animalFactory = new AnimalFactory(); Animal A = animalFactory.getAnimal("小狗A"); Animal B = animalFactory.getAnimal("小狗B"); Animal C = animalFactory.getAnimal("小狗C"); Animal A1 = animalFactory.getAnimal("小狗A"); A.eat(new Person("主人A")); A.eat(new Person("主人B")); A.eat(new Person("主人C")); A.eat(new Person("主人D")); } }
在上述代码里,拥有相同name属性的Dog类只会创建一个,避免了因为重复创建Dog而对系统的额外开销
应用场景:当系统中存在大量相同或相似的对象可以来使用享元模式,但是因为享元结构是存在一个额外的数据结构里(此处是Map),这也是一个额外的维护成品,所以需要相同的对象足够多时才有必要使用享元模式。