享元模式 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:/ ...
随机推荐
- mip-link 组件功能升级说明
背景描述 某个页面被多少页面引用(在其他页面上有指向这个页面的 a 标签),是搜索引擎判断这个页面价值的其中一个因子.这里的搜索引擎不只是指百度,还包括国内外其他的搜索引擎. MIP 在最初设计 MI ...
- 【机器学习基础】熵、KL散度、交叉熵
熵(entropy).KL 散度(Kullback-Leibler (KL) divergence)和交叉熵(cross-entropy)在机器学习的很多地方会用到.比如在决策树模型使用信息增益来选择 ...
- Java PDF页面设置——页面大小、页边距、纸张方向、页面旋转
下面的示例将介绍通过Java编程来对PDF页面进行个性化设置的方法,包括设置页面大小.页边距.纸张方向.页面旋转等.这里有如下多种页面大小尺寸可供选择: 同时,设置文档内容旋转时,可支持如下角度进行内 ...
- 从On-Premise本地到On-Cloud云上运维的演进
摘要: 从用户的声音中,我们听到用户对稳定.弹性.透明的诉求,我们也在不断升级ECS的运维能力和体验,助力用户建立主动运维体系,赋能业务永续运行.为了让大家更好的了解和用好ECS弹性计算服务,从本期开 ...
- 入门者必看!SharePoint之CAML总结(实战)
分享人:广州华软 无名 一. 前言 在SharePoint中,不支持直接操作数据库,但开发过程中,避免不了查询数据,那么,在SharePoint中如何查询数据? 当然是使用CAML语法. 二. 目录 ...
- 【error】Gradle sync failed: Unable to start the daemon process.【已解决】
---恢复内容开始--- 在克隆GIT项目后,Android Studio 报错: Gradle sync failed: Unable to start the daemon process. Th ...
- phpmyadmin登陆错误:The requested URL /phpmyadmin was not found on this serve
解决方法: 首先,重新安装apache2: sudo dpkg-reconfigure -plow phpmyadmin 配置时记得选择apache2 如果仍然无法登陆,再对phpmyadmin和a ...
- Windows Server 2016-Hyper-V网络虚拟化概述
在 Windows Server 2016 和虚拟机管理器中,Microsoft 提供的端到端网络虚拟化解决方案. 有构成了 Microsoft 的网络虚拟化解决方案的五个主要组件: Windows ...
- ERROR 1129 (HY000): mysqladmin flush-hosts
mysql报错:ERROR 1129 (HY000): Host * is blocked because of many connection errors; unblock with 'mysql ...
- WaitGroup
WaitGroup在go语言中,用于线程同步,单从字面意思理解,wait等待的意思,group组.团队的意思,WaitGroup就是指等待一组,等待一个系列执行完成后才会继续向下执行. 先说说Wait ...