c++ 设计模式概述之享元

类写的不够规范,目的是为了缩短篇幅,实际中其不要这样做。

参考文章:

  1、 http://c.biancheng.net/view/1371.html

 

1、概述

  A、享元,我的理解是: 共享的模块单元。实现的是复用代码。

  B、非享元,非享元类型要作为享元的接口的参数。   

 

2.、模式的结构
  享元模式的主要角色有如下。
  A、 抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
  B、 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
  C、 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
  D、 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

  

3、范例

  例如: 需要接受组播数据,组播ip相同,端口不同。收到的数据单独处理。

4、抽象享元角色

// 抽象共享单元
class fw_adress
{
public:
    virtual void operation(unshared_unit port) = 0;
};

 

5、具体享元

// 具体共享角色
class fly_weight_mine : public fw_adress
{
public:
    fly_weight_mine(std::string str_ip)
    {
        _udp_cast_ip = str_ip;

        cout << "\n 具体共享IP【 " << str_ip.c_str() << " 】被创建\n";
    }

    void operation(unshared_unit port)
    {
        cout << "\n 具体共享IP【 " << _udp_cast_ip.c_str() << " 】被调用,        ";
        cout << "非共享端口=" << port.get_port() <<"\n";
    }

private:
    std::string _udp_cast_ip;
};

 

6、非共享元

// 非共享模块
class unshared_unit
{
public:
    unshared_unit(int port) { _port = port; }

    int get_port() { return _port; }

private:
    int _port;
};

 

7、享元工厂

  工厂负责创建对象,用map维护了一个对象集

// 享元工厂,负责生产对应的对象
class flyweight_factory
{
public:

    // 释放资源
    virtual ~flyweight_factory()
    {
        for each(auto index in _map_adress)
        {
            if (index.second)
            {
                cout << "\n 正在释放对象 = " << index.first.c_str();
                delete index.second;
            }
        }
    }


    // 工厂负责创建对应的对象
    fw_adress* get_element(std::string str_ip)
    {
        fw_adress* pret_val = nullptr;
        std::map<std::string, fw_adress* > :: iterator& it = _map_adress.find(str_ip);


        // 1、 找到了, 说明已经创建,就返回已经创建的对象
        if (_map_adress.end() != it)
        {
            pret_val = it->second;
            cout << "已经找到【 " << str_ip.c_str() << " 】,放回已经创建的对象\n";
        }
        // 2、 没有找到,就创建
        else
        {
            pret_val = new fly_weight_mine(str_ip);

            // 2.1 创建失败
            if (nullptr == pret_val)
                cout << "\n\n 创建失败, str_ip = " << str_ip.c_str() << endl;
            // 2.2 创建成功
            else
                _map_adress.insert(make_pair(str_ip, pret_val));
        }

        return pret_val;
    }

private:

    // 维护对象使用,提高内存使用效率
    std::map<std::string, fw_adress *> _map_adress;
};

 

8、调用

void call_fly_weight()
{
    std::unique_ptr<flyweight_factory> pfact(new(std::nothrow) flyweight_factory);
    if (!pfact)
    {
        cout << "\n\n 享元 工厂创建失败";
        return;
    }

    // 内部管理,无需外界释放

    // 组播IP
    std::string str_udp1("233.100.100.199");
    std::string str_udp2("233.100.100.200");
    // 组播端口
    unshared_unit us1(10086);
    unshared_unit us2(10087);
    unshared_unit us3(10088);
    unshared_unit us4(10089);
    unshared_unit us5(20086);


    cout << "\n 1、下面开始创建对象:\n";
    fw_adress *fw1 = pfact->get_element(str_udp1);
    fw_adress *fw2 = pfact->get_element(str_udp1);
    fw_adress *fw3 = pfact->get_element(str_udp1);

    fw_adress *fw11 = pfact->get_element(str_udp2);
    fw_adress *fw12 = pfact->get_element(str_udp2);

    cout << "\n\n 2、对象创建完毕,下面开始调用非享元模块\n";

    if (fw1)
        fw1->operation(us1);

    if (fw2)
        fw2->operation(us2);

    if (fw3)
        fw3->operation(us3);

    if (fw11)
        fw11->operation(us4);

    if (fw12)
        fw12->operation(us5);
}

 

9、输出结果:

 

posted @ 2020-08-12 20:25  mohist  阅读(194)  评论(0编辑  收藏  举报