当前位置: 首页 > news >正文

网站建设营销型号的区别相似图片在线查找

网站建设营销型号的区别,相似图片在线查找,wordpress 首页图没了,电子商务网站建设与运营的试题重修设计模式-结构型-享元模式 复用不可变对象,节省内存 享元模式(Flyweight Pattern)核心思想是通过共享对象方式,达到节省内存和提高性能的目的。享元对象需是不可变对象,因为它会被多处代码共享使用,要避…

重修设计模式-结构型-享元模式

复用不可变对象,节省内存

享元模式(Flyweight Pattern)核心思想是通过共享对象方式,达到节省内存和提高性能的目的。享元对象需是不可变对象,因为它会被多处代码共享使用,要避免一处代码对享元进行了修改,影响到其他使用它的代码。

享元模式的实现非常简单,主要是通过工厂模式,在工厂类中,通过一个 Map 或者 List 来缓存已经创建过的享元对象,来达到复用的目的。

举个例子,在线象棋游戏:

象棋可同时容纳上万个房间同时进行游戏,每个房间最基础的是象棋和棋盘。一副象棋有32个棋子,如果后每个房间都创建相同的棋子对象,就是千万级别的,对任何系统都是个挑战。

分析这个例子,棋子的字和颜色是固定的几个,跟场景无关;场景相关的只有只有棋子的坐标。那其实可以把棋子不变的部分抽取出来,设计为享元对象,让所有棋子共享,从而让每个棋子对象变得更轻量。

未使用享元模式的棋子对象:

//棋子
data class ChessPieceOld(val id: Long,val text: String,val color: ChessPieceUnit.Color,val positionX: Int,val positionY: Int
) {
}

当对象大量创建时,几个固定的属性(id、text、color)会大量重复,冗余占用内存。这时可以将这几个属性抽出,设计为享元类,并使用带缓存的工厂来生成享元对象:

//棋子固定信息-享元类
data class ChessPieceUnit(val id: Long, val text: String, val color: Color) {enum class Color {RED, BLACK}
}//生成棋子-带缓存的创建工厂
class ChessPieceFactory {companion object {//享元对象池private val chessPiece = hashMapOf(1 to ChessPieceUnit(1, "車", ChessPieceUnit.Color.RED),2 to ChessPieceUnit(2, "馬", ChessPieceUnit.Color.BLACK),//...)fun getChessPiece(id: Int): ChessPieceUnit {return chessPiece[id]!!}}
}//棋子
data class ChessPiece(val piece: ChessPieceUnit, val positionX: Int, val positionY: Int) {
}//棋盘
class ChessBoard() {private val chessPieces: HashMap<Int, ChessPiece> = hashMapOf()fun init() {chessPieces.put(1, ChessPiece(ChessPieceFactory.getChessPiece(1), 0, 1))chessPieces.put(2, ChessPiece(ChessPieceFactory.getChessPiece(1), 0, 1))//...}fun move(chessPieceId: Int, positionX: Int, positionY: Int) {//...}
}

使用享元后,所有棋子的固定部分共同引用数量有限的享元对象,每个棋子对象变得更为轻量,内存中存储的冗余信息大大减少,避免了大量相似对象的开销,提高了系统资源的利用率。

注意上面的例子,使用享元模式后,棋子对象的数量并没有变化,只是对象比之前小了很多。消耗内存最多的成员变量已经被移动到很少的几个享元对象中了,这几个享元对象会被上千个情境小对象复用,无需再重复存储相同数据。

享元模式在 Java 语言中的应用

1.Java 中的字符串常量池

String 类会利用享元模式来复用相同的字符串常量,当某个字符串常量第一次被用到的时候,存储到常量池中,之后再用到的时候,直接引用常量池中已经存在的即可,不需要重复创建对象,通过下面代码可以验证。

//字符串常量池
String s1 = "秋意浓";
String s2 = "秋意浓";
String s3 = new String("秋意浓");//直接new出对象,绕过了Java的常量池优化
System.out.println(s1 == s2);   //输出:true
System.out.println(s1 == s3);   //输出:false

2.基本类型包装类

基本类型的包装类(如Integer 、Long、Short、Byte 等),也都利用了享元模式来缓存 -128 到 127 之间的数据。因为对于大部分应用来说这个区间是最常用的数值,如果预先创建所有值的享元对象不仅会占用大量内存,也会让类加载时间过长。

以 Integer 类型为例:

//包装类型的享元
Integer n1 = 1;
Integer n2 = 1;
Integer n3 = 129;
Integer n4 = 129;
System.out.println(n1 == n2);   //输出:true
System.out.println(n3 == n4);   //输出:false

因为 129 超出了享元对象池区间,所以每次会返回新的对象,两个对象地址不同,输出 false。Integer 享元部分源码如下:

public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}
}

可以通过 JDK 参数修改缓存池上限(下限不支持修改):

//方法一:
-Djava.lang.Integer.IntegerCache.high=255
//方法二:
-XX:AutoBoxCacheMax=255

在使用 Java 进行编码时,要尽量避免直接 new 出包装类型或者字符类型对象,如 String s = new String("aaa")Integer n = new Integer(1),这样会绕过系统的享元模式,创建重复对象。推荐直接使用自动装箱语法,如:Integer n = 1,或通过类型工厂的方式:Integer n = Integer.valueof(1)

上面两个场景都是享元模式在 Java 中的应用,只是实现略有不同:Integer 类中要共享的对象,是在类加载的时候就一次性创建好的;String 类的享元,是在某个字符串第一次被用到的时候,才创建并存储到常量池中的,相当于懒加载方式。

享元模式的类似设计

1.享元模式 vs 单例

虽然享元模式的实现和单例的变体多例非常相似,但它们的设计意图不同:享元模式是为了对象复用,节省内存。而多例是为了限制对象的个数。

2.享元模式 vs 对象池

虽然享元模式和对象池都是为了复用,但他们的“复用”也是不同的概念:

  • 对象池中的“复用”可以理解为“重复使用”,使用时被使用者独占,使用完成后放回池中,主要目的是节省时间。
  • 享元模式中的“复用”可以理解为“共享使用”,在整个生命周期中,都是被所有使用者共享的,主要目的是节省空间。

总结

当一个系统中存在大量重复对象的时候,我们就可以利用享元模式,将对象设计成享元,在内存中只保留一份实例,供多处代码引用,这样可以减少内存中对象的数量,以起到节省内存的目的。

http://www.hengruixuexiao.com/news/25320.html

相关文章:

  • 聊城网站制作公司北京百度网讯人工客服电话
  • 做网站费用会计分录怎么做seo网站分析报告
  • 吉林长春有做网站的吗东莞市网络seo推广价格
  • 网站优化及推广公司企业营销策略分析论文
  • 东莞网站设计的公司百度服务中心人工客服
  • 店面设计要素南京百度搜索优化
  • 做网站时怎么裁切存图抖音推广怎么做
  • 自己的电脑建网站湖南正规关键词优化首选
  • 爱站网关键字查询百度应用商店官网
  • 政府网站建设经验材料seo网站优化培训公司
  • 网站做会员用什么源码海外互联网推广平台
  • 淘宝客商品推广网站建设口碑营销的成功案例
  • 北京移动网站建设公司排名网店seo
  • 时尚网站的建设策划企业培训权威机构
  • 动态网站制作视频教程长沙网站se0推广优化公司
  • 物流网站模板网络推广发展
  • 网站优化内容原创如何做营销推广
  • 网站程序模块项目外包平台
  • 网站板块怎么做广州seo网站营销
  • 如何让网站做网页适配网站优化怎么做
  • 高端品牌衣服排行榜前十名seo技术培训机构
  • 专业手机移动网站建设关键词网络推广企业
  • 做网站的系统windows优化大师软件介绍
  • 域名备案查询网站备案信息查询阿里云万网域名注册
  • 建设工程质量协会网站品牌推广方案思维导图
  • 福田做商城网站建设哪家公司靠谱百度电视剧风云榜
  • 咸阳哪里做网站网络运营推广是做什么的
  • 网站开发产品描述电脑培训班一般要学多久
  • 安徽省公路建设行业协会网站福州seo推广
  • 网站被人做跳转本周新闻热点10条