享元模式---Flyweight

享元模式—Flyweight

1.模式定义:

享元模式(Flyweight ):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似状态变化很小,可以实现对象的多次复用

2.模式结构

  • flyweight:抽象享元
  • 具体享元角色:
  • concrete_flyweight1:具体享元角色1
  • concrete_flyweight2:具体享元角色2
  • flyweight_factory:享元工厂

3.代码分析

  • 3.1 main.cpp
#include"flyweight_factory.hpp"
#include<iostream>
using namespace std;


int main(int argc, char const *argv[])
{
    flyweight_factory ff;
    auto val1 = ff.get_flyweight("1");
    val1->operate();

    auto val2 = ff.get_flyweight("1");
    val2->operate();

    auto val3 = ff.get_flyweight("11");
    val3->operate();

    auto val4 = ff.get_flyweight("11");
    val4->operate();

    return 0;
}

  • 3.2 抽象享元: flyweight.hpp
#ifndef FLYWEIGHT_HPP
# define FLYWEIGHT_HPP

#include<string>
using namespace std;

// 抽象享元
class flyweight
{
private:
    string m_intrinsic; // 内部状态:可以共享的相同内容
protected:
    string m_Extrinsic; // 外部状态:不能共享的内容
public:
    flyweight(string Extrinsic){
        m_Extrinsic = Extrinsic;
    }
    ~flyweight(){}

    string get_intrinsic() {
        return m_intrinsic;
    }

    void set_intrinsic(string intrinsic) {
        m_intrinsic = intrinsic;
    }

    virtual void operate(){}
};

#endif // FLYWEIGHT_HPP

  • 3.3 具体享元角色: concrete_flyweight.hpp
#ifndef CONCRETE_FLYWEIGHT_HPP
# define CONCRETE_FLYWEIGHT_HPP

#include"flyweight.hpp"
#include<string>
#include<iostream>
using namespace std;

// 具体享元角色


// 具体享元角色1
class concrete_flyweight1: public flyweight
{

public:
    concrete_flyweight1(string Extrinsic):flyweight(Extrinsic){}

    ~concrete_flyweight1(){

    }

    void operate() {
        cout << "concrete_flyweight1::operate" << endl;
    }
};


// 具体享元角色2
class concrete_flyweight2: public flyweight
{

public:
    concrete_flyweight2(string Extrinsic):flyweight(Extrinsic){}

    ~concrete_flyweight2(){}

    void operate() {
       cout << "concrete_flyweight2::operate" << endl;       
    }
};

#endif // CONCRETE_FLYWEIGHT_HPP

  • 3.4 享元工厂: flyweight_factory.hpp
#ifndef FLYWEIGHT_FACTORY_HPP
# define FLYWEIGHT_FACTORY_HPP

#include<map>
#include<string>
#include"flyweight.hpp"
#include"concrete_flyweight.hpp"
using namespace std;


// 享元工厂
class flyweight_factory
{
private:
    static map<string, flyweight*> pool;
public:
    flyweight_factory(){}
    ~flyweight_factory(){
        for (auto it = pool.begin(); it != pool.end(); ++it) {
            delete it->second;
            it->second = nullptr;
        }
    }

    static flyweight* get_flyweight(string Extrinsic) {
        auto it = pool.find(Extrinsic);
        if (it != pool.end()) {
            return it->second;
        } else if ((Extrinsic.size()%2) == 0) {
            flyweight* fw2 = new concrete_flyweight2(Extrinsic);
            pool[Extrinsic] = fw2;
            return fw2;
        }

        flyweight* fw1 = new concrete_flyweight1(Extrinsic);
        pool[Extrinsic] = fw1;
        return fw1;
    }
};
// 初始化池
map<string, flyweight*> flyweight_factory:: pool = map<string, flyweight*>();


#endif // FLYWEIGHT_FACTORY_HPP

  • 3.5 实验结果:
concrete_flyweight1::operate
concrete_flyweight1::operate
concrete_flyweight2::operate
concrete_flyweight2::operate

4.优缺点

  • 4.1 优点

    • 4.1.1 相似对象内存共享,减少内存占用率,大大减少对象的创建和销毁,提高服务性能。
  • 4.2 缺点

    • 4.2.1 提高了系统复杂性,需要将对象分离出外部状态[不能共享的内容]和内部状态[可共享的内容]。

5.模式分析

  • 5.1 享元模式目的是通过对象池化共享技术,解决系统对相似对象的频繁重复创建和销毁,对系统性能的影响,主要是减少内存占用空间;

  • 5.2 享元模式主要使用了对象池、工厂方法设计模式、分离共享对象的内部和外部状态[通过外部状态查找共享对象],实现对象的多次复用。

6.实例:考试报名(go代码实现)

  • 类图:

  • 6.0: main.go

package main

import (
	"fmt"
	"./Flyweight"
)

func test_flyweight() {
	sign_pool := flyweight.NewSignFactory()
	for i := 0; i < 5; i++ {
		subject := "subject" + strconv.FormatInt(int64(i), 10)
		for j := 0; j < 30; j++ {
			address := "address" + strconv.FormatInt(int64(j), 10)
			key := subject + address
			val, isNew := sign_pool.GetSignInfo(key)
			// 一大败笔
			if !isNew {
				val.SetId((i + 1) * j)
				val.SetSubject(subject)
				val.SetPostAddress(address)
			}
		}
	}

	sign_info, isNew := sign_pool.GetSignInfo("subject1address1")
	fmt.Println("sign info:", *sign_info, " <====> new", isNew)
}

func main() {
	test_Flyweight()
}
  • 6.1:共享报名信息:SignInfo.go
package flyweight

// 共享报名信息
type SignInfo struct {
	id          int
	location    string
	subject     string
	postAddress string
}

func NewSignInfo() *SignInfo {
	return &SignInfo{}
}

func (si *SignInfo) SetId(id int) {
	si.id = id
}

func (si *SignInfo) GetId() (id int) {
	return si.id
}

func (si *SignInfo) SetLocation(location string) {
	si.location = location
}

func (si *SignInfo) GetLocation() (location string) {
	return si.location
}

func (si *SignInfo) SetSubject(subject string) {
	si.subject = subject
}

func (si *SignInfo) GetSubject() (subject string) {
	return si.subject
}

func (si *SignInfo) SetPostAddress(postAddress string) {
	si.postAddress = postAddress
}

func (si *SignInfo) GetPostAddress() (postAddress string) {
	return si.postAddress
}

  • 6.2: 报名工厂:SignFactory.go
package flyweight

// 报名工厂
type SignFactory struct {
	Pool map[string]*SignInfo
}

func NewSignFactory() *SignFactory {
	return &SignFactory{
		Pool: make(map[string]*SignInfo),
	}
}

func (sf *SignFactory) GetSignInfo(key string) (ret *SignInfo, new bool) {
	val, ok := sf.Pool[key]
	if ok {
		ret = val
	} else {
		ret = NewSignInfo()
		sf.Pool[key] = ret
	}
	return sf.Pool[key], ok
}

  • 6.3 执行结果:
sign info: {2  subject1 address1}  <====> new true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值