本帖最后由 古月不傲 于 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;
}
// 总结
// 优点:对于需要频繁调用的类建议使用单例模式
// 缺点:似乎没什么缺点 |