享元模式(大话设计模式)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;
}
相关推荐
爱吃生蚝的于勒2 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
失落的香蕉5 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
ChoSeitaku7 小时前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
DdddJMs__1357 小时前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
娃娃丢没有坏心思8 小时前
C++20 概念与约束(2)—— 初识概念与约束
c语言·c++·现代c++
ahadee9 小时前
蓝桥杯每日真题 - 第11天
c语言·vscode·算法·蓝桥杯
In_life 在生活10 小时前
设计模式(四)装饰器模式与命令模式
设计模式
瞎姬霸爱.10 小时前
设计模式-七个基本原则之一-接口隔离原则 + SpringBoot案例
设计模式·接口隔离原则
No0d1es10 小时前
2024年9月青少年软件编程(C语言/C++)等级考试试卷(九级)
c语言·数据结构·c++·算法·青少年编程·电子学会
鬣主任11 小时前
Spring设计模式
java·spring boot·设计模式