设计模式之享元模式

享元模式 模式介绍

享元模式可以理解为一个共享池的概念,即将一个对象缓存起来,下次再用的时候直接在缓存中获取,这样就不用重新创建对象,达到了节省内存、优化程序效率的优点。比如我们常用的String 和 数据库的连接池都是运用了该模式的思想。

设计模式之享元模式

应用场景

当程序中需要大量的细粒度对象,这些对象内容相似,并且可以按照两种状态区分的时候,就可以使用该模式进行设计。

优缺点

优点

由于创建的对象都被缓存了起来,所以在此请求相同的对象的时候,就不用在重新创建对象,直接从缓存中获取该对象即可。

节省了内存开销和程序的效率。

缺点

增加系统的理解难度。

需要将对象分为两种状态并且根据这两种状态(内部、外部)来控制是否进行对象的创建。

需要维护一个共享池,可以理解为工厂模式的实现。

例子介绍

比如我们现在有一个需求,需要在一块画布上随机位置,展示一个圆,这个圆分为四种颜色,分别为 “红、蓝、黄、绿” , 如果使用普通的做法来做就是,客户端发起请求,服务端接收后,根据请求的颜色去创建相应的圆形对象,然后赋予坐标。

package cn.hsh.study.flyweight.ordinary; /** * @author shaohua * @date 2021/4/22 19:41 */ public class Circular { private String color; private int x; private int y; public Circular(String color, int x, int y) { this.color = color; this.x = x; this.y = y; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } @Override public String toString() { return "Circular{" + "color='" + color + '\'' + ", x=" + x + ", y=" + y + '}'; } } package cn.hsh.study.flyweight.ordinary; /** * @author shaohua * @date 2021/4/22 19:41 */ public class Client { public static void main(String[] args) { Circular red = new Circular("red", 1, 10); System.out.println(red); } }

结果如下:

设计模式之享元模式

综上我们可以看到,客户端每次请求的时候都会创建一个新的对象,如果请求了1000次红色圆形那么就会创建1000个圆形对象出来,这个可以发现,除了坐标不同,1000个对象颜色是一样的,这里我们就可以将 颜色 和 坐标,分为内部状态和外部状态,内部状态为颜色可以进行共享但是不可以修改,外部状态就是坐标,不可以共享,但是可以随着客户端的调用而修改。 看代码 ↓

package cn.hsh.study.flyweight; /** * @author shaohua * @date 2021/4/20 19:40 */ public class Circular { private String color; private int x; private int y; public String getColor() { return color; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public Circular(String color) { this.color = color; } @Override public String toString() { return "Circular{" + "color='" + color + '\'' + ", x=" + x + ", y=" + y + '}'; } }

首先定义实体对象类,这个可以继承图形抽象类,但是我这里为了节省就直接写死了一个类。

package cn.hsh.study.flyweight.factory; import cn.hsh.study.flyweight.Circular; import java.util.HashMap; import java.util.Map; /** * @author shaohua * @date 2021/4/20 19:41 */ public class FlyWeightFactory { private static Map<String, Circular> pools = new HashMap<String, Circular>(16); public static Circular factory(String color, int x, int y){ Circular circular; if(pools.containsKey(color)){ System.out.println("检测到共享池中存在该颜色直接返回"); circular = pools.get(color); } else { circular = new Circular(color); } circular.setX(x); circular.setY(y); pools.put(color, circular); return circular; } }

注意 这里是整个享元模式的核心,也就是我们上面说的工厂类。每次请求的时候使用内部状态(颜色)为key,然后外部状态根据客户端可以随意修改。最后返回。

package cn.hsh.study.flyweight; import cn.hsh.study.flyweight.factory.FlyWeightFactory; import java.util.LinkedList; import java.util.List; /** * @author shaohua * @date 2021/4/19 18:45 */ public class Client { public static void main(String[] args) { Circular red = FlyWeightFactory.factory("red", 1, 10); Circular blue = FlyWeightFactory.factory("blue", 2, 20); Circular yellow = FlyWeightFactory.factory("yellow", 3, 30); Circular green = FlyWeightFactory.factory("green", 4, 40); Circular red1 = FlyWeightFactory.factory("red", 5, 50); Circular blue1 = FlyWeightFactory.factory("blue", 6, 60); List<Circular> circulars = new LinkedList<Circular>(); circulars.add(red); circulars.add(blue); circulars.add(yellow); circulars.add(green); circulars.add(red1); circulars.add(blue1); for (Circular circular : circulars) { System.out.println(circular.toString()); } System.out.println(red == red1); System.out.println(blue == blue1); } }

这是客户端调用,直接看结果 ↓

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpydxw.html