设计模式--享元模式
Posted bai3535
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--享元模式相关的知识,希望对你有一定的参考价值。
享元模式
含义:
说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。
比如我们每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象“adam“,下次再创建相同的字符 串”adam“时,只是把它的引用指向”adam“,这样就实现了”adam“字符串再内存中的共享。
核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。享元对象能够做到共享的关键是区分了内部状态和外部状态。
内部状态:可以共享,不会随环境变化而改变。
外部状态:不可以共享,会随环境变化而改变。
1) FlyweightFactory享元工厂类
创建并管理享元对象,享元池一般设计成键值对。
2) FlyWeight抽象享元类
通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态。
3) ConcreteFlyWeight具体享元类
为内部状态提供成员变量进行存储
4) UnsharedConcreteFlyWeight非共享享元类
不能被共享的子类可以设计为非共享享元类
图示:
package com.offcn.designpattern.flyweight; import java.util.HashMap; import java.util.Map; public class FlyweightDemo { public static void main(String[] args) { ConcreteFlyWeight chess1 = new ConcreteFlyWeight("黑色"); ConcreteFlyWeight chess2 = new ConcreteFlyWeight("黑色"); System.out.println(chess1); System.out.println(chess2); System.out.println("======添加坐标====="); chess1.position(new Coordinate(10,10)); chess2.position(new Coordinate(20,20)); } } //1) FlyweightFactory享元工厂类 class FlyWeightFactory{ //创建并管理享元对象,享元池一般设计成键值对。 private static Map<String,ConcreteFlyWeight> map = new HashMap<>(); public static ConcreteFlyWeight getChess(String color){ if(map.get(color) != null){ return map.get(color); }else{ ConcreteFlyWeight cfw = new ConcreteFlyWeight("黑色"); map.put(color,cfw); return cfw; } } } //2) FlyWeight抽象享元类 interface FlyWeigth{ //棋子颜色,内部状态 String getColor(); //棋子位置,外部状态 void position(Coordinate c); } //3) ConcreteFlyWeight具体享元类 class ConcreteFlyWeight implements FlyWeigth{ //为内部状态提供成员变量进行存储 private String color; public ConcreteFlyWeight(String color) { this.color = color; } @Override public String getColor() { return color; } @Override public void position(Coordinate c) { System.out.println("棋子颜色:"+color); System.out.println("棋子位置:"+c.getX()+".."+c.getY()); } } //4) UnsharedConcreteFlyWeight非共享享元类 class Coordinate{ private int x,y; public Coordinate(int x, int y) { this.x = x; this.y = y; } 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; } }
输出:
优点:
1) 极大减少内存中对象的数量
2) 相同或相似对象内存中只存一份,极大的节约资源,提高系统性能
3) 外部状态相对独立,不影响内部状态
缺点:
1) 模式较复杂,使程序逻辑复杂化
2) 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长,用时间换取了空间
使用场景:内存属于稀缺资源,不要随便浪费,如果有很多个完全相同或相似的对象,我们可以通过享元模式节省内存。可以在任何“池”中操作,比如线程池,数据库池。
String类的设计也是享元模式。
以上是关于设计模式--享元模式的主要内容,如果未能解决你的问题,请参考以下文章