Android设计模式--享元模式

水不激不跃,人不激不奋

一,定义

使用共享对象可有效地支持大量的细粒度的对象

享元模式是对象池的一种实现,用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象共享,避免创建过多对象的效果,这样一来就可以提升性能,避免内存溢出等。

在享元模式中会建立一个对象容器,在经典的享元模式中该容器为一个Map,它的键是享元对象的内部状态,它的值就是享元对象本身。客户端程序通过这个内部状态从享元工厂中获取享元对象,如果有缓存,则使用缓存对象,否则创建一个享元对象并且存入容器中,这样一来就避免了创建过多对象的问题。

二,使用场景

1,系统中存在大量的相似对象

2,细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,就是说对象没有特定身份

3,需要缓冲池的场景

三,角色介绍

Flyweight:享元对象抽象基类或接口

ConcreteFlyweight:具体的享元对象

FlyweightFactory:享元工厂,负责管理享元对象池和创建享元对象

四,使用案例

假设在吃鸡游戏中,每局游戏都会有100个玩家参与游戏,所以每局游戏都会创建100个玩家角色,如果一个玩家进行了10局游戏,他的角色就会被创建10次。这样就会造成频繁的GC,从而影响性能。如果我们使用享元模式,将玩家的姓名作为key,玩家角色作为value存放在内存中,这样就不会频繁的去创建玩家角色,避免造成不必要的资源浪费。

首先,创建一个玩家角色接口作为享元对象抽象接口,该接口定义玩家自己选择皮肤玩游戏:

public interface Player {
    
    /**
     * 玩游戏
     * @param skin 自己选择的皮肤
     * */
    void playGame(String skin);
}

然后创建具体的享元对象 :

public class ConcretePlayer implements Player{

    private String name;

    public ConcretePlayer(String name) {
        this.name = name;
    }

    @Override
    public void playGame(String skin) {
        System.out.println("玩家"+name+"使用"+skin+"角色玩游戏");
    }
}

最后创建享元工厂:

public class PlayerFactory {

    private static HashMap map =new HashMap<>();

    public static Player createPlayer(String name){
        if(map.get(name)==null){
            System.out.println("创建新的角色");
            ConcretePlayer concretePlayer =new ConcretePlayer(name);
            map.put(name,concretePlayer);
            return concretePlayer;
        }else {
            System.out.println("从缓存中拿取角色");
            ConcretePlayer player = (ConcretePlayer) map.get(name);
            return player;
        }
    }
}

使用:

Player player = PlayerFactory.createPlayer("N港之王");
player.playGame("红螳螂");
Player player1 = PlayerFactory.createPlayer("N港之王");
player1.playGame("黄螳螂");
Player player2 = PlayerFactory.createPlayer("N港之王");
player2.playGame("紫螳螂");

输出:

Android设计模式--享元模式_第1张图片

这样,即使玩家使用同一角色玩了好多把游戏,都只创建了一次角色,其余的都是从缓存中获取的

五,总结

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

享元模式的优点在于它大幅度地降低内存中对象的数量,但是,它做到这一点所付出的代价也是很高的。

享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

参考文献:Android源码设计模式解析与实战

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