《golang设计模式》第二部分·结构型模式-06-享元模式(Flyweight)

文章目录

  • 1. 概述
    • 1.1角色
    • 1.2 类图
  • 2. 代码示例
    • 2.1 设计
    • 2.2 代码
    • 2.3 类图示例

1. 概述

享元(Flyweight)模式采用共享方式向客户端提供数量庞大的细粒度对象。

所谓细粒度对象,是指实现了业务细节并相互独立的对象。细粒度对象是一种相对概念,一般不会进行更小粒度的拆分。

1.1角色

  • 抽象享元(Flyweight):
    • 通常是一个接口或抽象类
    • 它声明了具体享元类的公共方法
  • 具体享元(Concrete Flyweight)
    • 实现了抽象享元
    • 包含内部状态和外部状态
      • 内部状态:不可以被改变
      • 外部状态:可以被改变
    • 通常每一个具体享元类提供唯一的享元对象(可参考单例模式)
  • 享元工厂(Flyweight Factory):
    • 负责创建和管理享元角色
    • 它是享元的聚合,通常为:HashMap[key]Flyweight

当客户对象请求一个享元 对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在 的话,则创建一个新的享元对象。

1.2 类图

Client
FlyweightFactory
-flyweights:HashMap
+GetFlyweight(key:key)
ConcreteFlyweight
-IntrinsicState:Data
-extrinsicState:Data
+service(extrinsicStat:Data)
«interface»
Flyweight
+service(extrinsicState:Date)

2. 代码示例

2.1 设计

  • 定义一个抽象棋子(抽象享元)
  • 它的实现是 黑子、白子两个实际享元
    • 它的不变部分:颜色、形状
      • 它的Create()方法用来设置这些不可变部分
    • 它的可变部分:位置
      • 它的Set()方法用来设置位置
  • 定义一个享元工厂
    • 它应该包含两个享元
      • 1号享元黑子
      • 2号享元白子
    • 它的Get方法用来生产棋子
      • 如果有需要的棋子则返回查到的结果
      • 如果没有需要的棋子则创建该棋子
  • 调用
    • 创建一个享元工厂
    • 下第一颗子
      • 用享元工厂Get()方法实例化一个黑子
        • 此时享元工厂中没有黑子享元,它会创建一个黑子享元并返回。(当然这个过程用户看不出来,想看的话你可以在这之前打印享元工厂或者调试)
      • 用黑子的Set()方法设置这颗棋子的位置
      • 查看结果
    • 下第二颗子,也是白子的第一颗子
      • 用享元工厂Get()方法实例化一个白子

        • 此时享元工厂中没有白子享元,它会创建一个白子享元并返回。(当然这个过程用户看不出来,想看的话你可以在这之前打印享元工厂或者调试)
      • 用黑子的Set()方法设置这颗棋子的位置

      • 查看结果

    • 下第三颗子,也是黑子的第三颗子
      • 用享元工厂Get()方法实例化一个黑子
        • 此时享元工厂已经有黑子享元,它会直接返回这个享元。(当然这个过程用户看不出来,想看的话你可以在这之前打印享元工厂或者调试)
      • 用黑子的Set()方法设置这颗棋子的位置
      • 查看结果

2.2 代码

package mainimport ("errors""fmt"
)//定义一个抽象享元
type Flyweight interface {Create()Set(x int64, y int64)Get()
}
//定义一个实际享元(白色棋子)
type ConcreteFlyweightA struct {//它的不变部分Color stringShape string//它的可变部分PostX int64PostY int64
}
//定义设置不变部分的方法(设置棋子本身)
func (c *ConcreteFlyweightA) Create() {c.Color = "黑色"c.Shape = "圆形"
}
//定义设置可变部分的方法(棋子的位置)
func (c *ConcreteFlyweightA) Set(x int64, y int64) {c.PostX = xc.PostY = y
}
//查看方法
func (c *ConcreteFlyweightA) Get() {fmt.Printf("%+v\n", c)
}
//定义另一个具体享元(黑子),和第一个类似
type ConcreteFlyweightB struct {Color stringShape stringPostX int64PostY int64
}
//定义设置不变部分的方法(设置棋子本身)
func (c *ConcreteFlyweightB) Create() {c.Color = "白色"c.Shape = "圆形"
}
//定义设置可变部分的方法(棋子的位置)
func (c *ConcreteFlyweightB) Set(x int64, y int64) {c.PostX = xc.PostY = y
}
//查看方法
func (c *ConcreteFlyweightB) Get() {fmt.Printf("%+v\n", c)
}
//定义享元工厂,它包含所需的享元且用key标识
type FlyweightFactory struct {Flyweights map[int64]Flyweight
}
//定义创建享元的方法。如果找到就返回,找不到就创建
func (f *FlyweightFactory) Get(id int64) (flyweight Flyweight, err error) {flyweight, ok := f.Flyweights[id]if ok {return flyweight, nil} else {switch id {case 1:flyweight = &ConcreteFlyweightA{}flyweight.Create()f.Flyweights[1] = flyweightreturn flyweight, nilcase 2:flyweight = &ConcreteFlyweightB{}flyweight.Create()f.Flyweights[2] = flyweightreturn flyweight, nildefault:errors.New("id无效")return nil, err}}
}func main() {//实例化一个享元工厂flyweightFactory := FlyweightFactory{Flyweights: make(map[int64]Flyweight),}fmt.Println("=========黑棋落第一个子=========")//实例化第一个黑子,因为享元工厂中没有复合条件的棋子,因此会创建一个享元返回flyweight001, err := flyweightFactory.Get(1)if err != nil {return}//设置该棋子的位置flyweight001.Set(3, 3)//查看结果flyweight001.Get()fmt.Println("=========白棋落第一个子=========")//实例化第一个白子,因为享元工厂中没有复合条件的棋子,因此会创建一个享元返回flyweight002, err := flyweightFactory.Get(2)if err != nil {return}//设置该棋子的位置flyweight002.Set(17, 4)//查看结果flyweight002.Get()fmt.Println("=========黑棋落第二个子=========")//实例化第二个黑子,此时享元工厂有复合条件的享元,返回查到的结果(但是我们封装到工厂里,用户并不能察觉是创建还是复制)flyweight003, err := flyweightFactory.Get(1)if err != nil {return}//设置该棋子的位置flyweight003.Set(3, 17)//查看结果flyweight003.Get()
}
  • 输出
=========黑棋落第一个子=========
&{Color:黑色 Shape:圆形 PostX:3 PostY:3} 
=========白棋落第一个子=========
&{Color:白色 Shape:圆形 PostX:17 PostY:4}
=========黑棋落第二个子=========
&{Color:黑色 Shape:圆形 PostX:3 PostY:17}

2.3 类图示例

这里我们的客户端实际是调用了Flyweight接口
当然我们也可以如示例中一样直接调用每一个实际享元

«interface»
Flyweight
+Create()
+Set(x int64, y int64)
+Get()
ConcreteFlyweightA
+Color:string
+Shape:string
+PostX:int64
+PostY:int64
+Create()
+Set(x int64, y int64)
+Get()
ConcreteFlyweightB
+Color:string
+Shape:string
+PostX:int64
+PostY:int64
+Create()
+Set(x int64, y int64)
+Get()
FlyweightFactory
+Flyweights:HashMap
+Get(id int64) (flyweight Flyweight, err error)
Client

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/136644.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT---day3---9.19

1> 完成文本编辑器的保存工作 ui界面&#xff1a; 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QFontDialog> #include <QMessageBox> #include <QColor> #include <QColorDialog> #include <QFo…

电工三级证(高级)实战项目:信号交通灯的PLC控制

实训目的 掌握比较指令掌握时钟指令掌握时间同步的方法 控制要求 PLC设备:Siemens S7-200 要求:按下起动按钮SB1后&#xff0c;东西方向绿灯亮20s&#xff0c;之后再闪烁绿灯3s&#xff0c;之后黄灯亮3s&#xff0c;最后红灯亮26s&#xff1b;同时&#xff0c;南北方向红灯亮…

【链表】K 个一组翻转链表-力扣 25 题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

知识付费平台开发技术实践:构建数字学习的未来

引言 知识付费平台的兴起正在塑造着数字学习的未来。本文将介绍一些关键的技术实践&#xff0c;帮助开发者构建强大的知识付费平台&#xff0c;提供出色的数字学习体验。 1. 选择适当的技术栈 在开始知识付费平台的开发之前&#xff0c;首要任务是选择适当的技术栈。这包括…

【解决Win】“ 无法打开某exe提示无法成功完成操作,因为文件包含病毒或潜在的垃圾软件“

在下载某个应用程序&#xff0c;打开时出现了“无法成功完成操作因为文件包含病毒或潜在垃圾”的提示&#xff0c;遇到这个情况怎么解决&#xff1f; 下面为大家分享故障原因及具体的处理方法。 故障原因 是由于杀毒 防护等原因引起的。 解决方案 打开Windows 安全中心 选择…

BUU [HCTF 2018]Hideandseek

BUU [HCTF 2018]Hideandseek 考点&#xff1a; 软连接读取任意文件Flask伪造session/proc/self/environ文件获取当前进程的环境变量列表random.seed()生成的伪随机数种子MAC地址(存放在/sys/class/net/eth0/address文件) 国赛的时候遇见过软连接&#xff0c;这次再来学习一下…

方案:基于AI烟火识别与视频技术的秸秆焚烧智能化监控预警方案

一、方案背景 为严控秸秆露天焚烧&#xff0c;改善环境空气质量&#xff0c;各省相继发布秸秆禁烧工作内容。以安徽省为例&#xff0c;大气污染防治联席会议下发了该省2020年秸秆禁烧工作部署通知。2020年起&#xff0c;气象局将对全省秸秆焚烧火点实施卫星全年全时段监测&…

指针笔试题讲解(让指针变得简单易懂)

数组名的理解 : 数组名就是首元素地址 但是有两个例外&#xff1a; 1. sizeof&#xff08;数组名&#xff09;这里的数组名表示整个数组的大小&#xff0c;sizeof&#xff08;数组名&#xff09;计算的是整个数组的大小&#xff0c;单位是字节 2. &数组名 这里的数组…

9月19日作业

完成文本编辑器的保存工作-代码&#xff1a; void Widget::on_pushButton_4_clicked() {//创建保存文件对话框QString filename QFileDialog::getSaveFileName(this,"保存文件","./","All(*.*);;Text files (*.txt)");//创建一个文件对象&…

福建厦门航空飞机发动机零部件检测3D测量尺寸偏差比对-CASAIM中科广电

航空航天是一个创新型发展国家的尖端命脉&#xff0c;代表着一个国家科学技术的先进水平。在航空航天工业的发展和组成领域中&#xff0c;对于在制造业中的航空航天产品零部件精度要求十分严苛&#xff0c;从前期的设计、中期建造、后期维修检测&#xff0c;任何一个环节、任何…

java CAS详解(深入源码剖析)

CAS是什么 CAS是compare and swap的缩写&#xff0c;即我们所说的比较交换。该操作的作用就是保证数据一致性、操作原子性。 cas是一种基于锁的操作&#xff0c;而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住&#xff0c;等之前获得锁的线程释放锁之后&am…

Nginx配置负载均衡时访问地址无法生效

场景还原 今天有小伙伴练习Nginx配置负载均衡时总是无法使用配置好的网址访问 配置文件信详情 http {# 负载均衡 后端IP地址和端口 webservers 策略 轮询upstream webservers{server 192.168.1.100:8080 weight90; server 127.0.0.1:8080 weight10; }server{listen 80;ser…

C#使用OpenCv(OpenCVSharp)图像轮廓多边形逼近和轮廓最小矩形实例

本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像轮廓多边形逼近和轮廓最小矩形实例。 多边形逼近的目的是减少轮廓的点数,但看起来轮廓形状差不多。 最小矩形:面积更小的矩形,把轮廓包围起来实例 创建winform项目,添加控件和事件 添加类 using System; using…

学习路之PHP--laravel postman 提交表单出现419错误

问题图片 解决&#xff1a; 白名单 有时候你可能希望设置一组不需要 CSRF 保护的 URL 。例如&#xff0c;如果你正在使用 Stripe 处理付款并使用了他们的 webhook 系统&#xff0c;你会需要从 CSRF 的保护中排除 Stripe webhook 处理程序路由&#xff0c;因为 Stripe 不知道要发…

VSCode『SSH』连接服务器『GUI界面』传输

前言 最近需要使用实验室的服务器训练带有 GUI 画面的 AI 算法模型&#xff08;pygame&#xff09;&#xff0c;但是我是使用 SSH 连接的&#xff0c;不能很好的显示模型训练的效果画面&#xff0c;所以下面将会讲解如何实现 SSH 连接传输 Linux GUI 画面的 注&#xff1a;我们…

vs2022 创建一个同时支持.net480和.net6.0的WPF项目

新建WPF项目&#xff0c;不要选.NET Framework框架的。如下图所示&#xff0c;选择第一个。&#xff08;选择.NET Framework框架改成.net6.0会报错&#xff09; 用记事本打开项目的csproj文件&#xff0c;修改TargetFrameworks标签&#xff0c;如下所示&#xff1a; <Pro…

解决flutter不识别yaml里面配置的git项目

解决办法找到相应的 git路径&#xff0c;然后手动 git pull 暂时先用这个笨方法&#xff0c;后面有更好的解决办法了再说 studio 自己拉取的项目里面没有ios 和lib包

STM32-无人机-电机-定时器基础知识与PWM输出原理

电机控制基础——定时器基础知识与PWM输出原理 - 掘金单片机开发中&#xff0c;电机的控制与定时器有着密不可分的关系&#xff0c;无论是直流电机&#xff0c;步进电机还是舵机&#xff0c;都会用到定时器&#xff0c;比如最常用的有刷直流电机&#xff0c;会使用定时器产生PW…

5.2 磁盘CRC32完整性检测

CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法&#xff0c;校验算法可以通过计算应用与数据的循环冗余校验&#xff08;CRC&#xff09;检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测&#xff0c;…

纯js实现html指定页面导出word

因为最近做了范文网站需要&#xff0c;所以要下载为word文档&#xff0c;如果php进行处理&#xff0c;很吃后台服务器&#xff0c;所以想用前端进行实现。查询github发现&#xff0c;确实有这方面的插件。 js导出word文档所需要的两个插件&#xff1a; FileSaver.js jquery.w…