享元模式 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:/ ...
随机推荐
- H5 新特性之 fileReader 实现本地图片视频资源的预览
大家好 !! 又见面了, 今天我们来搞一搞 H5的新增API FileReader 真是一个超级超级方便的API呢!!!很多场景都可以使用.......... 我们先不赘述MDN文 ...
- Docker 快速开始
1. 概念 对于开发人员和系统管理员来说,Docker是一个使用容器开发.部署和运行应用程序的平台.使用Linux容器部署应用程序称为容器化.容器并不新鲜,但是将它们用于轻松部署应用程序却很新鲜. ...
- user 不在 sudoers 文件中。此事将被报告。
在使用sudo -i或su root命令时,被提示出“user不在 sudoers 文件中.此事将被报告”的错误信息.这是因为当前登录的账号不在sudo权限里面.sudo命令可以让你以root身份执行 ...
- angular-froala-wysiwyg 富文本编辑器使用及遇到的坑
介绍: angular-froala-wysiwyg: froala editor 的angular版本,支持Angular 2, Angular 4, Angular 5, Angular 6 an ...
- DSAPI显示PNG异形窗体
使用DSAPI实现PNG异形窗体,注意,该窗体为层样式窗体,以PNG或32位带透明通道的图像合成到屏幕,此方法不会触发窗体的重绘,故原窗体(包括其子控件)均不会显示,如果需要更新画面,需要重新用代码等 ...
- c#在pictureBox控件上绘制多个矩形框及删除绘制的矩形框
在pictureBox上每次只绘制一个矩形框,绘制下一个矩形框时上次绘制的矩形框取消,代码如链接:https://www.cnblogs.com/luxiao/p/5625196.html 在绘制矩形 ...
- [PHP]日志处理error_log()函数和配置使用
1.error_log($message,$message_type,$destination,$extra_headers)函数, 2.message_type 是0,发送信息到php.ini配置的 ...
- vue3+typescript引入外部文件
vue3+typescript中引入外部文件有几种方法 (eg:引入echarts) 第一种方法: 1 indext.html中用script引入 <div id="app" ...
- 安卓4.0以上系统怎么不用root激活XPOSED框架的方法
在大多单位的引流或业务操作中,基本上都需要使用安卓的高端技术Xposed框架,近期,我们单位购买了一批新的安卓4.0以上系统,基本上都都是基于7.0以上版本,基本上都不能够刷入root超级权限,即便是 ...
- DataPipeline联合Confluent Kafka Meetup上海站
Confluent作为国际数据“流”处理技术领先者,提供实时数据处理解决方案,在市场上拥有大量企业客户,帮助企业轻松访问各类数据.DataPipeline作为国内首家原生支持Kafka解决方案的“iP ...