【设计模式】11、flyweight 享元模式

news/2024/10/19 23:34:40/

文章目录

  • 十一、flyweight
    • 11.1 pool 连接池
      • 11.1.1 pool_test.go
      • 11.1.2 pool.go
      • 11.1.3 conn.go
    • 11.2 chess_board
      • 11.2.1 chess_test.go
      • 11.2.2 chess.go

十一、flyweight

https://refactoringguru.cn/design-patterns/flyweight

大量重复的对象, 如果很消耗资源, 没必要每次都初始化, 可以共用, 共享. 这就是 flyweight 享元模式.

各种池技术: 线程池, 数据库连接池, http 网络连接池, 都是应用场景

参考: 共享单车示例
https://www.bilibili.com/video/BV1Ka4y1L7jg/?spm_id_from=333.337.search-card.all.click&vd_source=5dfe92471f5072eaffbf480e25acd82d

11.1 pool 连接池

11flyweight/111pool
├── conn.go
├── pool.go
├── pool_test.go
└── readme.md

11.1.1 pool_test.go

package _11poolimport ("github.com/stretchr/testify/require""testing"
)/*
=== RUN   TestPoolWithSize1
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 申请连接资源, 开始
[连接池] 归还连接资源, 成功
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
--- PASS: TestPoolWithSize1 (0.00s)
PASS
*/
func TestPoolWithSize1(t *testing.T) {conns := []conn{&dbConn{}}p := NewPool(conns)c1, err := p.getConn()require.NoError(t, err)require.NotNil(t, c1)c1.connect()c2, err := p.getConn()require.Error(t, err)require.Nil(t, c2)p.putConn(c1)c3, err := p.getConn()require.NoError(t, err)require.NotNil(t, c3)c3.connect()
}/*
=== RUN   TestPoolWithSize5
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 归还连接资源, 成功
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 归还连接资源, 成功
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 归还连接资源, 成功
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 归还连接资源, 成功
[连接池] 申请连接资源, 开始
[连接池] 申请连接资源, 成功
数据库连接池: 连接中...
[连接池] 归还连接资源, 成功
--- PASS: TestPoolWithSize5 (0.00s)
PASS
*/
func TestPoolWithSize5(t *testing.T) {conns := []conn{&dbConn{}, &dbConn{}, &dbConn{}, &httpConn{}, &wsConn{}}p := NewPool(conns)for i := 0; i < len(conns); i++ {c, err := p.getConn()require.NoError(t, err)require.NotNil(t, c)c.connect()p.putConn(c)}
}

11.1.2 pool.go

package _11poolimport ("fmt"
)// IPool 连接池
type IPool interface {getConn() (conn, error)putConn(conn)
}// 连接池实现
type pool struct {connDict map[conn]struct{}
}func NewPool(conns []conn) IPool {connDict := map[conn]struct{}{}for _, c := range conns {connDict[c] = struct{}{}}return &pool{connDict: connDict,}
}// 获取连接
func (p *pool) getConn() (conn, error) {fmt.Println("[连接池] 申请连接资源, 开始")l := len(p.connDict)if l == 0 {return nil, fmt.Errorf("[连接池] 申请连接资源, 失败: 已无空闲连接资源")}fmt.Println("[连接池] 申请连接资源, 成功")var c connfor cIter := range p.connDict {c = cIterbreak}delete(p.connDict, c)return c, nil
}// 归还连接
func (p *pool) putConn(c conn) {if c == nil {return}p.connDict[c] = struct{}{}fmt.Println("[连接池] 归还连接资源, 成功")
}

11.1.3 conn.go

package _11poolimport "fmt"// 连接
type conn interface {connect()
}type dbConn struct{}func (c *dbConn) connect() {fmt.Println("数据库连接池: 连接中...")
}type httpConn struct{}func (c *httpConn) connect() {fmt.Println("http连接池: 连接中...")
}type wsConn struct{}func (c *wsConn) connect() {fmt.Println("http连接池: 连接中...")
}

11.2 chess_board

象棋棋盘

11flyweight/112chess_board
├── chess.go
├── chess_test.go
└── readme.md

11.2.1 chess_test.go

package _12chess_boardimport ("github.com/stretchr/testify/require""testing"
)/*
=== RUN   TestChess
--- PASS: TestChess (0.00s)
PASS
*/
func TestChess(t *testing.T) {board1 := NewChessBoard()// board1.Move(1, 1, 2)board2 := NewChessBoard()// board2.Move(2, 2, 3)require.EqualValues(t, board1.chessPieces[1].Unit, board2.chessPieces[1].Unit)require.EqualValues(t, board1.chessPieces[2].Unit, board2.chessPieces[2].Unit)
}

11.2.2 chess.go

package _12chess_boardvar ChessPieceUnits = map[int]*ChessPieceUnit{1: {ID: 1, Name: "车", Color: "red"},2: {ID: 2, Name: "马", Color: "yellow"},3: {ID: 3, Name: "炮", Color: "blue"},
}// ChessPiece 棋子
type ChessPiece struct {Unit *ChessPieceUnitX    intY    int
}// ChessPieceUnit 棋子享元
type ChessPieceUnit struct {ID    intName  stringColor string
}// NewChessPieceUnit 创建棋子
func NewChessPieceUnit(id int) *ChessPieceUnit {return ChessPieceUnits[id]
}// ChessBoard 棋盘
type ChessBoard struct {chessPieces map[int]*ChessPiece
}func NewChessBoard() *ChessBoard {board := &ChessBoard{chessPieces: map[int]*ChessPiece{}}for id := range ChessPieceUnits {board.chessPieces[id] = &ChessPiece{Unit: NewChessPieceUnit(id),X:    0,Y:    0,}}return board
}// Move 移动棋子
func (c *ChessBoard) Move(id, x, y int) {c.chessPieces[id].X = xc.chessPieces[id].Y = y
}

http://www.ppmy.cn/news/1438386.html

相关文章

学习Rust的第11天:模块系统

Rust的模块系统可以使用它来管理不断增长的项目&#xff0c;并跟踪 modules 存储在何处。 Rust的模块系统是将代码组织成逻辑片段的有效工具&#xff0c;因此可以实现代码维护和重用。模块支持分层组织、隐私管理和代码封装。Rust为开发人员提供了多功能和可扩展的方法来管理项…

Ansible安装基本原理及操作(初识)

作者主页&#xff1a;点击&#xff01; Ansible专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月23日15点18分 Ansible 是一款功能强大且易于使用的IT自动化工具&#xff0c;可用于配置管理、应用程序部署和云端管理。它使用无代理模式&#xff08;agentles…

关于MCU核心板的一些常见问题

BGA植球与焊接&#xff08;多涂焊油&#xff09;&#xff1a; 【BGA芯片是真麻烦&#xff0c;主要是植锡珠太麻烦了&#xff0c;拆一次就得重新植】https://www.bilibili.com/video/BV1vW4y1w7oNvd_source3cc3c07b09206097d0d8b0aefdf07958 / NC电容一般有两种含义&#xff1…

ubuntu中可以查看照片的程序

ubuntu中可以查看照片的程序 在Ubuntu中&#xff0c;您可以使用多种图片查看器来查看照片。以下是几个常用的图片查看器&#xff1a; GIMP GIMP是一个免费的开源图片编辑器&#xff0c;它也可以用来查看和打印图片。 安装命令&#xff1a; sudo apt-get update sudo apt-ge…

Recommended Azure Monitors

General This document describes the recommended Azure monitors which can be implemented in Azure cloud application subscriptions. SMT incident priority mapping The priority “Blocker” is mostly used by Developers to prioritize their tasks and its not a…

安卓手机连接电脑实用技巧:实现文件传输与共享

在手机使用过程中&#xff0c;我们常常需要将手机中的文件传输到电脑&#xff0c;或者将手机与电脑进行共享。为了实现这一需求&#xff0c;掌握一些实用的安卓手机连接电脑技巧就显得尤为重要。本文将为您详细介绍2种简单、高效且安全的方法&#xff0c;让您轻松实现安卓手机与…

『FPGA通信接口』串行通信接口-IIC(2)EEPROM读写控制器

文章目录 1.EEPROM简介2.AT24C04简介3.逻辑框架设计4.随机读写时序5.仿真代码与仿真结果分析6.注意事项7.效果8.传送门 1.EEPROM简介 EEPROM (Electrically Erasable Programmable read only memory) 是指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。在嵌入…

去年十八,初识Java 2

我的Python和PHP是怎么学的&#xff1f;是直接写项目&#xff0c;在项目中学的。 不过…这招到 java 里好像不好使了QAQ 零、前置基础 1、类的继承 在 Java 中&#xff0c;extends 用于创建类的继承关系。当一个类继承另一个类时&#xff0c;它会获得父类的属性和方法&…