设计模式(11)——享元 Flyweight

24 篇文章 0 订阅
24 篇文章 3 订阅
目录:

设计模式学习笔记首页
设计模式(1)——抽象工厂 AbstractFactory
设计模式(2)——生成器 Builder
设计模式(3)——工厂方法 Factory Method
设计模式(4)——原型 Prototype
设计模式(5)——单例 Singleton
设计模式(6)——适配器 Adapter
设计模式(7)——桥接 Bridge
设计模式(8)——组合 Composite
设计模式(9)——装饰 Decorator
设计模式(10)——外观 Facade
设计模式(11)——享元 Flyweight
设计模式(12)——代理 Proxy
设计模式(13)——职责链 Chain Of Responsibility
设计模式(14)——命令 Command
设计模式(15)——解释器 Interpreter
设计模式(16)——迭代器 Iterator
设计模式(17)——中介者 Mediator
设计模式(18)——备忘录 Memento
设计模式(19)——观察者 Observer
设计模式(20)——状态 State
设计模式(21)——策略 Strategy
设计模式(22)——模板方法 Template Method
设计模式(23)——访问者 Visitor

十一、Flyweight(享元模式,对象结构型模式)

1. 意图:

  运用共享技术有效地支持大量细粒度的对象。

2. 适用:

  Flyweight 模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用 Flyweight 模式。
1. 一个应用程序使用了大量的对象。
2. 完全由于使用大量的对象,造成很大的存储开销。
3. 对象的大多数状态都可变为外部状态。
4. 如果删除对象的外部状态,那么可以用相对校少的共享对象取代很多组对象。
5. 应用程序不依赖于对象标识。由于 Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

3. 类图:

image

4. 中间层思考:

  享元模式在系统和直接使用细粒度对象之间加入一个享元工厂,这个工厂就是中间层。系统不再直接创建和使用对象,而是由这个工厂来负责创建对象,工厂内部对同一对象只会创建一次,保证对象都是共享的。

5. Flyweight 与 简单工厂

  享元模式与简单工厂模式有点像,都用到了工厂的概念。其实享元模式里面就是用到了简单工厂模式来管理细粒度对象。享元模式解决的问题是对象的共享,而工厂模式解决的问题是如何封装对象的创建过程。明白它们两解决的问题,就知道它们是两种完全不一样的模式。但是它们却可以完美地结合在一起,协同解决问题。

6. C++实现:

  1. 先编写一个 Flyweight 类,构造函数接收一个参数 instrinsicState 用于描述内部状态(不变部分)
  2. 包含一个函数 Operation(const string& extrinsicState) 用于操作外部状态(可变部分)
  3. 编写 Flyweight 的子类 ConcreteFlyweight
  4. 编写工厂类 FlyweightFactory, 包含一个函数 GetFlyweight(const string& key), 一个 vector<Flyweight*> _fly 用于存储已创建的 Flyweight
Flyweight.h
// Flyweight.h
#pragma once

#include <string>
using namespace::std;

class Flyweight {
public:
    virtual ~Flyweight();
    virtual void Operation(const string& extrinsicState);
    string GetIntrinsicState();
protected:
    Flyweight(string intrinsicState);
private:
    string _intrinsicState;
};

class ConcreteFlyweight : public Flyweight {
public:
    ConcreteFlyweight(string intrinsicState);
    ~ConcreteFlyweight();
    void Operation(const string& extrinsicState);
protected:
private:
};
Flyweight.cpp
//Flyweight.cpp
#include "Flyweight.h"
#include <iostream>
using namespace::std;

Flyweight::Flyweight(string intrinsicState) {
    this->_intrinsicState = intrinsicState;
}
Flyweight::~Flyweight() {}
void Flyweight::Operation(const string& extrinsicState){}
string Flyweight::GetIntrinsicState() {
    return this->_intrinsicState;
}

ConcreteFlyweight::ConcreteFlyweight(string intrinsicState) : Flyweight(intrinsicState) {
    cout << "ConcreteFlyweight Build..." << intrinsicState << endl;
}
ConcreteFlyweight::~ConcreteFlyweight() {}
void ConcreteFlyweight::Operation(const string& extrinsicState) {
    cout << "ConcreteFlyweight: 内蕴 [" << this->GetIntrinsicState() << "] 外蕴 [" << extrinsicState << "]" << endl;
}
FlyweightFactory.h
//FlyweightFactory.h
#pragma once
#include "Flyweight.h"
#include <string>
#include <vector>
using namespace::std;

class FlyweightFactory {
public:
    FlyweightFactory();
    ~FlyweightFactory();
    Flyweight* GetFlyweight(const string& key);
protected:
private:
    vector<Flyweight*> _fly;
};
FlyweightFactory.cpp
//FlyweightFactory.cpp

#include "FlyweightFactory.h"
#include <iostream>
#include <string>
#include <cassert>
using namespace::std;

FlyweightFactory::FlyweightFactory() {}
FlyweightFactory::~FlyweightFactory() {}
Flyweight* FlyweightFactory::GetFlyweight(const string& key) {
    vector<Flyweight*>::iterator it = _fly.begin();
    for (; it != _fly.end(); it++) {
        //找到了,就一起用
        if ((*it)->GetIntrinsicState() == key) {
            cout << "already created by users..." << endl;
            return *it;
        }
    }

    Flyweight* fw = new ConcreteFlyweight(key);
    _fly.push_back(fw);
    return fw;
}
main.cpp
//main.cpp
#include "Flyweight.h"
#include "FlyweightFactory.h"
#include <iostream>
using namespace::std;

int main(int argc, char* argv[]) {
    FlyweightFactory* fc = new FlyweightFactory();
    Flyweight* fw1 = fc->GetFlyweight("hello");
    Flyweight* fw2 = fc->GetFlyweight("world!");
    Flyweight* fw3 = fc->GetFlyweight("hello");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值