享元模式 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:/ ...
随机推荐
- Python和Python解释器
目录 Python介绍(了解) Python解释器发展史(了解) Python解释器(了解) CPython IPython PyPy Jython IronPython 安装Python解释器(掌握 ...
- 【转】asp.net基础-HttpModule
HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...
- Python爬虫入门教程 61-100 写个爬虫碰到反爬了,动手破坏它!
python3爬虫遇到了反爬 当你兴冲冲的打开一个网页,发现里面的资源好棒,能批量下载就好了,然后感谢写个爬虫down一下,结果,一顿操作之后,发现网站竟然有反爬措施,尴尬了. 接下来的几篇文章,我们 ...
- 两个月的Java实习结束,继续努力
前言 只有光头才能变强 2018年8月30日,今天我辞职了.在6月25号入职,到现在也有两个月时间了. 感受: 第一天是期待的:第一次将项目拉到本地上看的时候,代码很多,有非常多的模块,模块下又有da ...
- 一文助您成为Java.Net双平台高手
写在前面:本文乃标题党,不是月经贴,侧重于Web开发差异,或细节或概述,若有不对之处,还请各位读者本着友好互助的心态批评指正.由于博客园中.Neter较多(个人感觉),因此本文也可以作为.Neter到 ...
- aps .net MVC单用户登录
当不允许多用户同时登录一个帐号时,就需要一种机制,当再登录一个相同的帐号时,前面登录的人被挤下线. 原文地址:http://www.cnblogs.com/f23wangj/p/4984302.htm ...
- Android音视频之AudioRecord录音(一)
在音视频开发中,录音当然是必不可少的.首先我们要学会单独的录音功能,当然这里说的录音是指用AudioRecord来录音,读取录音原始数据,读到的就是所谓的PCM数据.对于录音来说,最重要的几个参数要搞 ...
- git tag本地删除以及远程删除
假设存在tag:12345 git tag -d 12345 #删除本地记录 git push origin :refs/tags/12345 #删除远程记录 PS: 如果您觉得我的文章对您有帮助,可 ...
- 记一次mongodb聚合查询
先说一下场景,产品中用到了简单的表单构造器,开始提供了一系列的控件,例如单行文本框.多行文本框.单选.复选.时间等,之后你可以拖拽控件自己组装你想要的表单……网上有很多的表单构造器,这里就不细说了,可 ...
- win7下建立超级隐藏账户
win7下建立超级隐藏账户 实验目的: 隐藏用户,不让管理员简单的发现 隐藏方法: 1.命令提示符中创建隐藏账户这种方法只能将账户在"命令提示符"中进行隐藏,而对于"计算 ...