Java设计模式 -- 享元模式

Java设计模式 – 享元模式

概念

如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用都创建新的对象。在享元模式中,由于需要构造和维护这些可以共享的对象,因此,常会出现一个工厂类,用于维护和创建对象。

结构

    享元工厂:用于创建具体享元类,维护相同的享元对象。它保证相同的享元对象可以被系统共享。即,其内部使用了类似单例模式的方法,当请求对象已经存在时,直接返回对象,不存在时,在创建对象。 抽象享元:定义需要共享的对象业务接口。享元类被创建出来总是为了实现某些特定的业务逻辑,而抽象享元便定义这些逻辑的语义行为。 具体享元类:实现抽象享元类的接口,完成某一具体逻辑。 客户端:使用享元模式的组件,通过享元工厂取得享元对象。

案例

我们学习了时,用的英雄的案例,那么我们继续以这个为例子。假设每一个英雄都是有类型的,比如法师、坦克、刺客等。这种类型我们可以顶一个类,但是如果每新建立一个英雄就要去新建一个“类型”类就会非常占用内存,此时我们就可以使用享元模式来解决。

创建Flyweight接口

public interface Flyweight {
          
   
    void operation(String hero);
}

创建ConcreteFlyweight(享元对象),实现接口

public class ConcreteFlyweight implements Flyweight{
          
   

    private String type;

    public ConcreteFlyweight(String type) {
          
   
        this.type = type;
    }

    @Override
    public void operation(String hero) {
          
   
        System.out.println("英雄是: " + hero + ", 类型: " + type);
    }
}

创建FlyweightFactory,用来维护享元池

public class FlyweightFactory {
          
   

    private static Map<String, Flyweight> map = new HashMap<>();

    public static Flyweight getFlyweight(String type) {
          
   
        if (map.containsKey(type)) {
          
   
            return map.get(type);
        }else {
          
   
            ConcreteFlyweight concreteFlyweight = new ConcreteFlyweight(type);
            map.put(type, concreteFlyweight);
            return concreteFlyweight;
        }
    }
    
    public static void getTotal() {
          
   
        System.out.println("总共创建了" + map.size() + "个对象");
    }

}

客户端测试

public class Client {
          
   
    public static void main(String[] args) {
          
   
        Flyweight f1 = FlyweightFactory.getFlyweight("坦克");
        Flyweight f2 = FlyweightFactory.getFlyweight("法师");
        Flyweight f3 = FlyweightFactory.getFlyweight("刺客");
        f1.operation("屠夫");
        f2.operation("冰女");
        f3.operation("影刺");
        f3.operation("幻刺");
        FlyweightFactory.getTotal();
    }
}
英雄是: 屠夫, 类型: 坦克
英雄是: 冰女, 类型: 法师
英雄是: 影刺, 类型: 刺客
英雄是: 幻刺, 类型: 刺客
总共创建了3个对象

优点

享元模式是一个非常简单的模式,它可以大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能,但它同时也提高了系统复杂性,需要分离出外部状态和内部状态,而且外部状态具有固化特性,不应该随内部状态改变而改变,否则导致系统的逻辑混乱。

场景

    系统中存在大量的相似对象。 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。 需要缓冲池的场景。
经验分享 程序员 微信小程序 职场和发展