吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1178|回复: 5
收起左侧

[讨论] 适配器、原型、单例模式

[复制链接]
古月不傲 发表于 2020-11-14 15:15
本帖最后由 古月不傲 于 2020-11-14 15:17 编辑

适配器模式
[C++] 纯文本查看 复制代码
#include <iostream>

using namespace std;

// 适配器模式
namespace adapter_pattern {
enum media_types
{
    MP3,
    MP4,
    WAV
};

// 抽象一个媒体播放器
class abstract_media_player 
{
public:
    virtual void play(media_types type, string name) = 0;
    virtual ~abstract_media_player() {}
};

// 抽象一个高级的媒体播放器
class abstract_advanced_media_player 
{
public:
    virtual void play_mp4(string name) = 0;
    virtual void play_wav(string name) = 0;
    virtual ~abstract_advanced_media_player() {}
};

// mp4播放器
class mp4_player : public abstract_advanced_media_player 
{
public:
    virtual void play_mp4(string name) override {
        printf("播放mp4类型:%s\n", name.c_str());
    }
    // 什么都不做
    virtual void play_wav(string name) override {}
};

// wav播放器
class wav_player : public abstract_advanced_media_player 
{
public:
    // 什么都不做
    virtual void play_mp4(string name) override {}
    virtual void play_wav(string name) override {
        printf("播放wav类型:%s\n", name.c_str());
    }
};

// 适配器 桥梁 包含一个高级的媒体播放器 让他拥有播放高级功能
class adapter_media_player : public abstract_media_player 
{
public:
    adapter_media_player(media_types type) {
        switch (type)
        {
        case MP4: {
            this->m_ab_adv = new mp4_player;
            break;
        }
        case WAV: {
            this->m_ab_adv = new wav_player;
            break;
        }   
        default: {
            this->m_ab_adv = nullptr;
            break;
        }  
        }
    }
    void play(media_types type, string name) {
        switch (type)
        {
        case MP4: {
            this->m_ab_adv->play_mp4(name);
            delete this->m_ab_adv;
            break;
        }
        case WAV: {
            this->m_ab_adv->play_wav(name);
            delete this->m_ab_adv;
            break;
        }   
        default: {
            printf("不支持该种类型!\n");
            break;
        }  
        }
    }
private:
    abstract_advanced_media_player *m_ab_adv;
};

// mp3播放器 让mp3包含一个适配器, 强行拥有播放其它格式的功能
class mp3_player : public abstract_media_player 
{
public:
    void play(media_types type, string name) override {
        switch (type)
        {
        case MP3: {
            printf("播放MP3类型:%s\n", name.c_str());
            break;
        }
        case MP4: case WAV: {
            this->m_adapter_player = new adapter_media_player(type);
            this->m_adapter_player->play(type, name.c_str());
            delete this->m_adapter_player;
            break;
        }
        default: {
            printf("不支持该种类型!\n");
            break;
        }  
        }
    }
    void own_something() {}
private:
    adapter_media_player *m_adapter_player;
};
}

// 可以看出只要new一个播放实例就好 它可以播放多种类型 
int main(void)
{
    using namespace adapter_pattern;

    abstract_media_player *mp3 = new mp3_player;
    mp3->play(MP3, "世间美好与你环环相扣");
    mp3->play(MP4, "暗香");
    mp3->play(WAV, "带你去旅行");

    delete mp3;


    return 0;
}

// 总结
// 优点:让一个类拥有多种功能
// 缺点:结构复杂,层层嵌套,破坏了类的单一原则性

原型模式
[C++] 纯文本查看 复制代码
#include <iostream>

using namespace std;

// 原型模式
namespace prototype_pattern {
// 抽象克隆类
class abstract_clone 
{
public:
    virtual abstract_clone *clone() = 0;
    virtual void print() = 0;
    virtual ~abstract_clone() {}
};

// 一个实例对象
class sheep : public abstract_clone 
{
public:
    sheep(const string &name, int age) : m_age(age)
    , m_name(name) {}
    sheep(const sheep &obj) : m_age(obj.m_age)
    , m_name(obj.m_name) {}
    abstract_clone *clone() override {
        return new sheep(*this);
    }
    void print() override {
        printf("name = %s age = %d\n", this->m_name.c_str(), this->m_age);
        printf("name = %p age = %p\n", &this->m_name, &this->m_age);
    }
private:
    string m_name;
    int m_age;
};
}

// 可以看出只是通过拷贝构造出另一个对象而已 目的是为了简化构造参数的传递,以及不破坏当前的对象
int main(void)
{
    using namespace prototype_pattern;
    
    abstract_clone *ab_xiyangyang = new sheep("喜羊羊", 5);
    ab_xiyangyang->print();
    abstract_clone *ab_clone = ab_xiyangyang->clone();
    ab_clone->print();

    delete ab_clone;
    delete ab_xiyangyang;
    return 0;
}

// 总结
// 优点:简化构造参数传递,不破坏当前的对象
// 缺点:似乎作用并不是很大

单例模式
[C++] 纯文本查看 复制代码
#include <iostream>

using namespace std;

// 单例模式
namespace single_pattern {
class skills 
{
public:
    // 通过公有接口返回一个实例对象 并且利用static的只初始化一次和局部不被释放的特性  保证了安全性和内存的有效利用
    static skills &get_instance() {
        static skills s;
        printf("%p\n", &s);
        return s;
    }
public:
    void cast_q() {
        printf("释放q技能\n");
    }
    void cast_w() {
        printf("释放w技能\n");
    }
    void cast_e() {
        printf("释放e技能\n");
    }
    void cast_r() {
        printf("释放r技能\n");
    }
private:
    skills() = default;
    // 禁止拷贝 赋值
    skills(const skills &obj) = delete;
    skills &operator==(const skills &obj) = delete;
    ~skills() = default;
private:
    static skills m_s;
};
}

// 可以看出实例对象使用的是相同的地址空间
int main(void)
{
    using namespace single_pattern;

    for (int i = 0; i < 1000; i++) {
        skills::get_instance().cast_q();
        skills::get_instance().cast_w();
        skills::get_instance().cast_e();
        skills::get_instance().cast_r();
    }

    return 0;
}

// 总结
// 优点:对于需要频繁调用的类建议使用单例模式
// 缺点:似乎没什么缺点

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

鸭子咯咯哒~ 发表于 2020-11-14 16:21
wow!对于我这样的新人来说很有帮助
BaseenHomles 发表于 2020-11-14 16:46
wlwyzyyq 发表于 2020-11-14 17:11
304775988 发表于 2020-11-14 19:21
可以,复习复习
大山GZ 发表于 2020-11-14 21:02
嚯,可以,还不赖嘛
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 11:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表