Android开发经验谈Android技术知识Android开发

享元模式

2019-04-10  本文已影响14人  Jackson杰

一 定义

享元模式是池技术的重要实现。

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

享元模式的定义为我们提出了两个要求,细粒度的对象和共享对象。我们知道创建过多的对象分配到内存中很容易造成内存溢出,享元模式就可以尽可能地减少内存的使用量,比较适用于可能存在大量重复对象的场景,通过共享技术,避免创建过多的对象。

先来了解两个概念:内部状态和外部状态

二 模式结构

角色介绍:

三 实例

public abstract class Flyweight {
    // 内部状态
    private String intrinsic;

    // 外部状态
    protected final String Extrinsic;

    // 要去享元角色必须接收外部状态
    public Flyweight(String extrinsic){
        this.Extrinsic=extrinsic;
    }

    // 定义业务操作
    public abstract void operate();

    // 内部状态的getter/setter

    public String getIntrinsic() {
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic) {
        this.intrinsic = intrinsic;
    }
}
public class ConcreteFlyweight extends Flyweight{
    // 接受外部状态
    public ConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    // 根据外部状态进行逻辑处理
    @Override
    public void operate() {
        // 业务处理

    }
}
public class UnsharedConcreteFlyweight extends Flyweight{

    public UnsharedConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate() {

    }
}
public class FlyweightFactory {
    // 定义一个池容器
    private static HashMap<String, Flyweight> pool = new HashMap<>();

    // 享元工厂
    public static Flyweight getFlyweight(String Extrinsic) {

        // 需要返回的对象
        Flyweight flyweight=null;

        // 在池中没有该对象
        if (pool.containsKey(Extrinsic)){
            flyweight=pool.get(Extrinsic);
            System.out.print("已有 " + Extrinsic + " 直接从池中取---->\n");
        }else {
            // 根据外部状态创建享元对象
            flyweight=new ConcreteFlyweight(Extrinsic);
            // 放置到池中
            pool.put(Extrinsic,flyweight);
            System.out.print("创建 " + Extrinsic + " 并从池中取出---->\n");
        }

        return flyweight;

    }
}
 Flyweight flyweightX = FlyweightFactory.getFlyweight("X");
 Flyweight flyweightY = FlyweightFactory.getFlyweight("Y");
  Flyweight flyweightZ = FlyweightFactory.getFlyweight("Z");
  Flyweight flyweightReX = FlyweightFactory.getFlyweight("X");
   Flyweight unsharedFlyweight = new UnsharedConcreteFlyweight("X");

我们以过年回家买火车票为例,过年回家买火车票是件痛苦的事情,很多人都用书票软件向服务端发出请求,对于每个请求,服务端必须做出应答。在用户设置了出发地和目的地后,每次请求都要返回查询结果,当无数的人请求时,如果每次都需要重新创建一个查询结果,那么必然造成大量重复对象的创建,销毁等,使得内存占用率高居不下,所以这个问题可以通过享元模式得到很好的解决。
对于一列火车来说,我们拿高铁举例,
不变的状态比如高铁的名字都是复兴号。
变化的状态是出发城市和终止城市。

public abstract class Ticket {

    // 内部状态
    private String name="和谐号";

    // 外部状态
    protected String from;
    protected String to;

    public Ticket(String from,String to){
        this.from=from;
        this.to=to;
    }

    // 定义业务逻辑,根据座位等级,显示价格
    public abstract void showTicketInfo(String seat);


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

}
public class TrainTicket extends Ticket{


    public TrainTicket(String from, String to) {
        super(from, to);
    }

    @Override
    public void showTicketInfo(String seat) {
        if (from.equals("北京") && to.equals("青岛")){
            switch (seat){
                case "business":
                    System.out.println(from+"到"+to+getName()+"列车:商务座的价格是988元!");
                    break;
                case "one":
                    System.out.println(from+"到"+to+getName()+"列车:一等座的价格是689元!");
                    break;
                case "two":
                    System.out.println(from+"到"+to+getName()+"列车:二等座的价格是298元!");
                    break;
            }
        }else if (from.equals("北京") && to.equals("济南")){
            switch (seat){
                case "business":
                    System.out.println(from+"到"+to+getName()+"列车:商务座的价格是598元!");
                    break;
                case "one":
                    System.out.println(from+"到"+to+getName()+"列车:一等座的价格是389元!");
                    break;
                case "two":
                    System.out.println(from+"到"+to+getName()+"列车:二等座的价格是186元!");
                    break;
            }
        }

    }
}
public class TicketFactory {

    // 定义一个池容器
    private static Map<String,Ticket> pool=new HashMap<>();

    // 享元工厂
    public static Ticket getTicket(String from,String to){
        String key=from+"-"+to;
        if (pool.containsKey(key)){
            System.out.println("使用缓存==>"+key);
            return pool.get(key);
        }else {
            System.out.println("创建对象==>"+key);
            Ticket ticket=new TrainTicket(from,to);
            pool.put(key, ticket);
            return ticket;
        }
    }
}

       Ticket ticket01=TicketFactory.getTicket("北京","青岛");
       ticket01.showTicketInfo("business");

       Ticket ticket02=TicketFactory.getTicket("北京","青岛");
       ticket02.showTicketInfo("one");

       Ticket ticket03=TicketFactory.getTicket("北京","青岛");
       ticket03.showTicketInfo("two");

       Ticket ticket04=TicketFactory.getTicket("北京","济南");
       ticket04.showTicketInfo("two");

从运行结果可以看出,除了第一次是创建的对象以外,其它的都是使用缓存的对象。

四 优缺点

五 使用场景

上一篇 下一篇

猜你喜欢

热点阅读