享元模式 FlyWeight 结构型 设计模式(十五)

意图
意图解析



考虑下图中的情景,这里面所有的“你”字,到底是不是同样的?
- 是,因为全部都是汉字“你”
- 不是,因为尽管都是汉字“你”,但是他们的字体,颜色,字号,却又明显不同,所以不是同样的

小结
享元工厂
示例代码
package flyweight;
public class Color {
public String Color;
public Color(String color) {
this.Color = color;
}
public String getColor() {
return Color;
}
}
package flyweight;
public abstract class Character {
public abstract String getValue(); public void display(Color color) {
System.out.println("字符: " + getValue() + " ,颜色: " + color.getColor());
}
}
package flyweight;
public class ChineseCharacter extends Character {
@Override
public String getValue() {
return "你";
}
}
package flyweight;
import java.util.HashMap;
public class CharacterFactory {
/**
* 单例模式 饿汉式创建
*/
private static CharacterFactory instance = new CharacterFactory();
/**
* 使用HashMap管理享元池
*/
private HashMap<String, Object> hm = new HashMap<>();
private CharacterFactory() {
Character character = new ChineseCharacter();
hm.put("你", character);
}
/**
* 单例全局访问接口获取工厂
*/
public static CharacterFactory getInstance() {
return instance;
} /**
* 根据key获取池中的对象
*/
public Character getCharacter(String key) {
return (Character) hm.get(key);
}
}


结构

客户端角色Client
客户端角色维护了对所有享元对象的引用

分类
单纯享元模式
package flyweight.simple;
public abstract class FlyWeight {
/**
* 抽象的业务逻辑方法,接受外部状态作为参数
*/
abstract public void operation(String outerState);
}
package flyweight.simple;
public class ConcreteFlyWeight extends FlyWeight {
private String innerState = null;
public ConcreteFlyWeight(String innerState) {
this.innerState = innerState;
}
/**
* 外部状态作为参数传递
*/
@Override
public void operation(String outerState) {
System.out.println("innerState = " + innerState + " outerState = " + outerState);
}
}
package flyweight.simple;
import java.util.HashMap;
public class FlyWeightFactory {
/**
* 单例模式 饿汉式创建
*/
private static FlyWeightFactory instance = new FlyWeightFactory();
/**
* 使用HashMap管理享元池
*/
private HashMap<String, Object> hm = new HashMap<>(); private FlyWeightFactory() {
}
/**
* 单例全局访问接口获取工厂
*/
public static FlyWeightFactory getInstance() {
return instance;
}
/**
* 根据innerState获取池中的对象
* 存在返回,不存在创建并返回
*/
public FlyWeight getFylWeight(String innerState) {
if(hm.containsKey(innerState)){
return (FlyWeight) hm.get(innerState);
}else{
FlyWeight flyWeight = new ConcreteFlyWeight(innerState);
hm.put(innerState,flyWeight);
return flyWeight;
}
}
}
package flyweight.simple;
public class Test {
public static void main(String[] args){
FlyWeightFactory flyWeightFactory = FlyWeightFactory.getInstance();
FlyWeight flyWeight1 = flyWeightFactory.getFylWeight("First");
FlyWeight flyWeight2 = flyWeightFactory.getFylWeight("Second");
FlyWeight flyWeight3 = flyWeightFactory.getFylWeight("First"); System.out.println(flyWeight1);
System.out.println(flyWeight2);
System.out.println(flyWeight3);
System.out.println(); flyWeight1.operation("outer state XXX");
flyWeight2.operation("outer state YYY");
flyWeight3.operation("outer state ZZZ");
}
}
复合享元模式

复合享元角色UnsharedConcreteFlyWeight
复合享元角色,也就是不可共享的,也被称为 不可共享的享元对象
但是一个复合享元对象可以分解为多个本身是单纯享元对象的组合
这些单纯的享元对象就又是可以共享的
package flyweight.composite;
public abstract class FlyWeight {
/**
* 抽象的业务逻辑方法,接受外部状态作为参数
*/
abstract public void operation(String outerState);
}
package flyweight.composite;
public class ConcreteFlyWeight extends FlyWeight {
private String innerState = null;
public ConcreteFlyWeight(String innerState) {
this.innerState = innerState;
}
/**
* 外部状态作为参数传递
*/
@Override
public void operation(String outerState) {
System.out.println("innerState = " + innerState + " outerState = " + outerState);
}
}
package flyweight.composite;
import java.util.ArrayList;
import java.util.List;
public class UnsharedConcreateFlyWeight extends FlyWeight {
private String innerState = null;
public UnsharedConcreateFlyWeight(String innerState) {
this.innerState = innerState;
} private List<FlyWeight> list = new ArrayList<>();
public void add(FlyWeight flyWeight) {
list.add(flyWeight);
}
@Override
public void operation(String outerState) {
for (FlyWeight flyWeight:list) {
flyWeight.operation(outerState);
}
}
}
package flyweight.composite;
import java.util.HashMap;
public class FlyWeightFactory {
/**
* 单例模式 饿汉式创建
*/
private static FlyWeightFactory instance = new FlyWeightFactory();
/**
* 使用HashMap管理享元池
*/
private HashMap<String, Object> hm = new HashMap<>();
/**
* 管理复合享元对象
*/
private HashMap<String, Object> compositeHm = new HashMap<>();
private FlyWeightFactory() {
}
/**
* 单例全局访问接口获取工厂
*/
public static FlyWeightFactory getInstance() {
return instance;
}
/**
* 根据innerState获取池中的对象
* 存在返回,不存在创建并返回
*/
public FlyWeight getFylWeight(String innerState) {
if(hm.containsKey(innerState)){
return (FlyWeight) hm.get(innerState);
}else{
FlyWeight flyWeight = new ConcreteFlyWeight(innerState);
hm.put(innerState,flyWeight);
return flyWeight;
}
}
/**
* 根据innerState获取池中的对象
* 存在返回,不存在创建并返回
*/
public UnsharedConcreateFlyWeight getCompositeFylWeight(String state) {
if(compositeHm.containsKey(state)){
return (UnsharedConcreateFlyWeight) compositeHm.get(state);
}else{
UnsharedConcreateFlyWeight flyWeight = new UnsharedConcreateFlyWeight(state);
compositeHm.put(state,flyWeight);
return flyWeight;
}
}
}
package flyweight.composite;
public class Test {
public static void main(String[] args){
FlyWeightFactory flyWeightFactory = FlyWeightFactory.getInstance();
FlyWeight flyWeight1 = flyWeightFactory.getFylWeight("First");
FlyWeight flyWeight2 = flyWeightFactory.getFylWeight("Second");
FlyWeight flyWeight3 = flyWeightFactory.getFylWeight("First"); System.out.println(flyWeight1);
System.out.println(flyWeight2);
System.out.println(flyWeight3); System.out.println("###########################################"); flyWeight1.operation("outer state XXX");
flyWeight2.operation("outer state YYY");
flyWeight3.operation("outer state ZZZ");
System.out.println("###########################################");
UnsharedConcreateFlyWeight compositeFlyWeight = flyWeightFactory.getCompositeFylWeight("composite");
compositeFlyWeight.add(flyWeight1);
compositeFlyWeight.add(flyWeight2);
compositeFlyWeight.operation("composite out state OOO");
}
}


使用场景
- 应用程序中使用了大量的对象
- 大量的对象明显增加了程序的存储运行开销
- 对象可以提取出内部状态,并且可以分离外部状态
总结
享元模式 FlyWeight 结构型 设计模式(十五)的更多相关文章
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- Java设计模式15:常用设计模式之享元模式(结构型模式)
1. Java之享元模式(Flyweight Pattern) (1)概述: 享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 设计模式 笔记 享元模式 Flyweight
//---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...
- 设计模式(十)享元模式Flyweight(结构型)
设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
随机推荐
- unison+inotify的Web目录同步方案
1.在Linux下做WEB目录文件同步 一般有如下几种方式: ----------------------------------------------- 1) nfs实现web数据共享 ...
- "元素隐式具有 “any” 类型,因为类型“Shared”没有索引签名"问题解决思路
最近在构建一个typescript项目时如下代码在项目框架里vscode报错元素隐式具有 "any" 类型,因为类型“Shared”没有索引签名;很有意思的是当我们单独的把这段代码 ...
- 初探机器学习之使用讯飞TTS服务实现在线语音合成
最近在调研使用各个云平台提供的AI服务,有个语音合成的需求因此就使用了一下科大讯飞的TTS服务,也用.NET Core写了一个小示例,下面就是这个小示例及其相关背景知识的介绍. 一.什么是语音合成(T ...
- 如何使用FluentMigrator进行数据库迁移
标题:如何使用FluentMigrator进行数据库迁移 地址:https://www.cnblogs.com/lwqlun/p/10649949.html 作者: Lamond Lu FluentM ...
- ab性能测试工具的使用
一.什么是ab ab,即Apache Benchmark,是一种用于测试Apache超文本传输协议(HTTP)服务器的工具. ab命令会创建很多的并发访问线程,模拟多个访问者同时对某一URL地址进行访 ...
- KnockOut 绑定之foreach绑定
foreach绑定对于数组中的每一个元素复制一节标记语言,也就是html,并且将这节标记语言和数组里面的每一个元素绑定.当我们呈现一组list数据,或者一个表格的时候,十分有用. 如果你绑定的数组是一 ...
- Java之品优购课程讲义_day06(7)
商品录入[SKU 商品信息]5.1 需求分析 基于上一步我们完成的规格选择,根据选择的规格录入商品的 SKU 信息,当用户选择相应的规格,下面的 SKU 列表就会自动生成,如下图:实现思路:实现思路: ...
- 学习web的第二天
之前因为技能大赛的原因,导致我这门课没有上.其实上学期是开Dreamweaver网页制作的课程的,所以老师讲的很快.我就利用课后时间去补漏,今天讲了HTML标签:1.标题标签<h1>~&l ...
- SuperMap iObject入门开发系列之六管线区域查询
本文是一位好友“托马斯”授权给我来发表的,介绍都是他的研究成果,在此,非常感谢. 管线区域查询功能针对单一管线图层进行区域多边形框选查询,然后将查询结果输出为列表,并添加定位和闪烁功能,效果如下图所示 ...
- 物理dataguard 正常切换 脚色转换,switchover_status 状态改变
正常切换切换前: 主库:SQL> select DATABASE_ROLE from v$database;DATABASE_ROLE----------------PRIMARY SQL> ...