zoukankan      html  css  js  c++  java
  • 设计模式学习使用go实现享元模式 Zhan

    享元模式

    定义

    享元模式(Flyweight),运用共享技术有效的支持大量细粒度的对象。

    享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。就是当一个系统中有大量的重复对象的时候,如果这些对象是不可变对象,我们就可以使用
    享元模式,将这些对象设计成享元,在内存只保存一份,供需要的代码使用,这样能减少内存中对象的数量,起到节省内存的作用。实际上,不仅仅相同对象可以设计成享元,对于相似对象,我们也可以将这些对象中相同的部分(字段)提取出来,设计成享元,让这些大量相似对象引用这些享元。

    不可变对象是函数初始化之后,他的状态不会改变了,也就是不会存在被修改的情况。

    优点

    大大减少对象的创建,降低系统的内存,使效率提高。

    缺点

    提高了系统的复杂度

    适用场景

    一个系统中有大量相同或者相似的对象,使用这些对象,会造成内存的大量消耗,这时候可以考虑使用享元模式

    代码实现

    我们都下过象棋,对于象棋一共有32枚棋子,每方各16枚。每次下棋使用的都是这32枚棋子,只是每次移动的棋子的位置。

    那么这32枚棋子就可以作为享元,每次下棋就不用重新初始化生成棋子。只需在棋盘中放置棋子的位子,下棋的时候,更改位置即可。

    // ChessPieceUnit ...
    type ChessPieceUnit struct {
    	id    int
    	text  string
    	color string
    }
    
    var pieces map[int]*ChessPieceUnit
    
    func init() {
    	pieces = make(map[int]*ChessPieceUnit, 32)
    	pieces[1] = &ChessPieceUnit{
    		id:    1,
    		text:  "马",
    		color: "BLACK",
    	}
    	pieces[2] = &ChessPieceUnit{
    		id:    2,
    		text:  "炮",
    		color: "BLACK",
    	}
    	// ...
    }
    
    func getChessPiece(chessPieceId int) *ChessPieceUnit {
    	return pieces[chessPieceId]
    }
    
    type ChessPiece struct {
    	chessPieceUnit *ChessPieceUnit
    	positionX      int
    	positionY      int
    }
    
    func newChessPiece(chessPieceId int, positionX, positionY int) *ChessPiece {
    	return &ChessPiece{
    		chessPieceUnit: getChessPiece(chessPieceId),
    		positionX:      positionX,
    		positionY:      positionY,
    	}
    }
    
    // 棋盘
    type ChessBoard struct {
    	chessPieces map[int]*ChessPiece
    }
    
    func (cb *ChessBoard) InitChessBoard() {
    	cb.chessPieces = make(map[int]*ChessPiece, 32)
    	cb.chessPieces[1] = newChessPiece(1, 0, 1)
    	cb.chessPieces[2] = newChessPiece(2, 0, 2)
    	// ...
    }
    
    // Move 下棋
    func (cb *ChessBoard) Move(chessPieceId int, positionX, positionY int) {
    	// TODO
    }
    

    享元模式和单例模式的区别

    单例模式:一个类只能创建一个对象。

    享元模式:一个类可以创建多个对象,每个对象被多处代码引用共享。实际上,享元模式有点类似于之前讲到的单例的变体:多例。

    单例对象可以是可变的。 享元对象是不可变的。

    实现上差不多,不过设计意图不同,享元模式是为了对象复用,节省内存,而应用多例模式是为了限制对象的个数。

    参考

    【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/享元模式
    【大话设计模式】https://book.douban.com/subject/2334288/
    【极客时间】https://time.geekbang.org/column/intro/100039001
    【享元模式】https://boilingfrog.github.io/2021/11/17/使用go实现享元模式/

  • 相关阅读:
    Android学习之天气预报简单版
    Android学习之Json数据的获取与解析
    getPath()返回路径包含的“%20”(空格)的处理
    自学php 之数据库连接编程
    bnuoj 1071 拼图++
    hdu 2489 Minimal Ratio Tree
    hdu 4720 Naive and Silly Muggles
    hdu 4725 The Shortest Path in Nya Graph
    经典算法学习:排序之希尔排序(壳排序)
    经典算法学习:排序之插入排序
  • 原文地址:https://www.cnblogs.com/ricklz/p/15566002.html
Copyright © 2011-2022 走看看