享元模式(大话设计模式)C/C++版本

享元模式

C++

cpp 复制代码
#include <iostream>
#include <string>
#include <map>
using namespace std;

// 用户类 用户网站的客户账号,是"网站"类的外部状态
class User
{
private:
    string m_name;

public:
    User(string name)
    {
        m_name = name;
    }
    std::string GetName()
    {
        return m_name;
    }
};

// 抽象网站类 定义对象的内部状态和外部状态及其对应的方法。
class WebSite
{
public:
    virtual ~WebSite() = default;
    virtual void Use(User user) = 0;
};

// 此处为具体网站类  实现抽象享元角色的方法,在具体的角色中,实现具体方法时需要注意将内部状态与外部状态区分开,不应出现二者同时被修改的方法。
class ConcreteWebSite : public WebSite
{
private:
    string m_name;

public:
    ConcreteWebSite(std::string name)
    {
        m_name = name;
    }
    void Use(User user) override
    {
        cout << "网站分类:" << m_name << "  用户:" + user.GetName() << endl;
    }
};

// 此处为网站工程类 负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,
// 如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
class WebSiteFactory
{
private:
    std::map<std::string, WebSite *> flyweights;

public:
    ~WebSiteFactory()
    {
        for (auto it = flyweights.begin(); it != flyweights.end(); ++it)
            delete it->second;
    }
    WebSite *GetWebSiteCategory(string key)
    {
        for (auto it = flyweights.begin(); it != flyweights.end(); ++it)
        {
            if (it->first == key)
                return it->second;
        }

        WebSite *website = new ConcreteWebSite(key);
        flyweights.insert(pair<std::string, WebSite *>(key, website));
        return website;
    }
    int GetWebSiteCount()
    {
        return flyweights.size();
    }
};

int main()
{
    WebSiteFactory f;

    WebSite *fx = f.GetWebSiteCategory("产品展示");
    fx->Use(User("小菜"));

    WebSite *fy = f.GetWebSiteCategory("产品展示");
    fy->Use(User("大鸟"));

    WebSite *fz = f.GetWebSiteCategory("产品展示");
    fz->Use(User("娇娇"));

    WebSite *fl = f.GetWebSiteCategory("博客");
    fl->Use(User("老顽童"));

    WebSite *fm = f.GetWebSiteCategory("博客");
    fm->Use(User("桃谷六仙"));

    WebSite *fn = f.GetWebSiteCategory("博客");
    fn->Use(User("南海鳄神"));

    cout << "得到网站分类总数:" << f.GetWebSiteCount() << endl;

    return 0;
}

C

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// 定义哈希表的节点结构体
typedef struct HashNode
{
    char *key;
    void *value;
    struct HashNode *next;
} HashNode;

// 定义哈希表结构体
typedef struct HashTable
{
    HashNode **table;
    size_t size;
} HashTable;

// 创建哈希表
HashTable *create_hash_table(size_t size)
{
    HashTable *hash_table = malloc(sizeof(HashTable));
    hash_table->table = malloc(sizeof(HashNode *) * size);
    hash_table->size = size;
    memset(hash_table->table, 0, sizeof(HashNode *) * size);
    return hash_table;
}

// 销毁哈希表
void destroy_hash_table(HashTable *hash_table)
{
    size_t i;
    for (i = 0; i < hash_table->size; ++i)
    {
        HashNode *node = hash_table->table[i];
        while (node)
        {
            HashNode *next = node->next;
            free(node->key);
            free(node->value);
            free(node);
            node = next;
        }
    }
    free(hash_table->table);
    free(hash_table);
}

// 计算哈希值
size_t hash(const char *key, size_t size)
{
    size_t hash = 5381;
    int c;
    while ((c = *key++))
    {
        hash = ((hash << 5) + hash) + c;
    }
    return hash % size;
}

// 在哈希表中插入键值对
bool insert_hash_table(HashTable *hash_table, const char *key, void *value)
{
    size_t index = hash(key, hash_table->size);
    HashNode *new_node = malloc(sizeof(HashNode));
    new_node->key = strdup(key);
    new_node->value = value;
    new_node->next = hash_table->table[index];
    hash_table->table[index] = new_node;
    return true;
}

// 从哈希表中获取值
void *get_from_hash_table(HashTable *hash_table, const char *key)
{
    size_t index = hash(key, hash_table->size);
    HashNode *node = hash_table->table[index];
    while (node)
    {
        if (strcmp(node->key, key) == 0)
        {
            return node->value;
        }
        node = node->next;
    }
    return NULL;
}

// 用户结构体
typedef struct User
{
    char *name;
} User;

// 网站结构体
typedef struct Website
{
    char *name;
} Website;

// 网站工厂结构体
typedef struct WebsiteFactory
{
    HashTable *flyweights;
} WebsiteFactory;

// 创建用户
User *create_user(const char *name)
{
    User *user = malloc(sizeof(User));
    user->name = strdup(name);
    return user;
}

// 销毁用户
void destroy_user(User *user)
{
    free(user->name);
    free(user);
}

// 创建网站
Website *create_website(const char *name)
{
    Website *website = malloc(sizeof(Website));
    website->name = strdup(name);
    return website;
}

// 销毁网站
void destroy_website(Website *website)
{
    free(website->name);
    free(website);
}

// 使用网站
void use_website(Website *website, User *user)
{
    printf("网站分类:%s  用户:%s\n", website->name, user->name);
}

// 创建网站工厂
WebsiteFactory *create_website_factory()
{
    WebsiteFactory *factory = malloc(sizeof(WebsiteFactory));
    factory->flyweights = create_hash_table(10);
    return factory;
}

// 销毁网站工厂
void destroy_website_factory(WebsiteFactory *factory)
{
    destroy_hash_table(factory->flyweights);
    free(factory);
}

// 从工厂获取网站
Website *get_website_category(WebsiteFactory *factory, const char *key)
{
    Website *website = get_from_hash_table(factory->flyweights, key);
    if (!website)
    {
        website = create_website(key);
        insert_hash_table(factory->flyweights, key, website);
    }
    return website;
}

int main()
{
    WebsiteFactory *f = create_website_factory();

    Website *fx = get_website_category(f, "产品展示");
    User *user_fx = create_user("小菜");
    use_website(fx, user_fx);
    destroy_user(user_fx);

    Website *fy = get_website_category(f, "产品展示");
    User *user_fy = create_user("大鸟");
    use_website(fy, user_fy);
    destroy_user(user_fy);

    Website *fz = get_website_category(f, "产品展示");
    User *user_fz = create_user("娇娇");
    use_website(fz, user_fz);
    destroy_user(user_fz);

    Website *fl = get_website_category(f, "博客");
    User *user_fl = create_user("老顽童");
    use_website(fl, user_fl);
    destroy_user(user_fl);

    Website *fm = get_website_category(f, "博客");
    User *user_fm = create_user("桃谷六仙");
    use_website(fm, user_fm);
    destroy_user(user_fm);

    Website *fn = get_website_category(f, "博客");
    User *user_fn = create_user("南海鳄神");
    use_website(fn, user_fn);
    destroy_user(user_fn);

    size_t count = 0;
    size_t i;
    for (i = 0; i < f->flyweights->size; ++i)
    {
        if (f->flyweights->table[i])
        {
            ++count;
        }
    }
    printf("得到网站分类总数:%zu\n", count);

    destroy_website_factory(f);

    return 0;
}
相关推荐
重生之绝世牛码12 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
荒古前25 分钟前
龟兔赛跑 PTA
c语言·算法
shinelord明38 分钟前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
嵌入式科普1 小时前
十三、从0开始卷出一个新项目之瑞萨RZN2L串口DMA接收不定长
c语言·stm32·瑞萨·e2studio·rzn2l
小林熬夜学编程3 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Jackey_Song_Odd3 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
A懿轩A4 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
半盏茶香4 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
字节高级特工5 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白6 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言