title: "modern C++ DesignPattern-Part1"
date: 2018-04-03T16:06:33+08:00
lastmod: 2018-04-03T16:06:33+08:00
draft: false
keywords: [设计模式]
tags: [设计模式, C++]
categories: []

现代c++改变了很多设计模式的实现方式,为了保持与时俱进,阅读了"Design Pattern in Modern C++"这本书,会记录下来在阅读中的一些心得体会,Part1主要包括 工厂模式,建造者模式与单例模式的现代实现


Factory

Abstract Factory

struct HotDrinkFactory {
virtual unique_ptr<HotDrink> make() const = 0; };
};
struct CoffeeFactory : HotDrinkFactory{
unique_ptr<HotDrink> make() const override {
return make_unique<Coffee>();
}}; class DrinkFactory {
map<string, unique_str<HotDrinkFactory>> hot_factories;
public:
DrinkFactory(){
hot_factories["coffee"] = make_unique<CoffeeFactory>();
hot_factories["tea"] = make_unique<TeaFactory>();
}
unique_ptr<HotDrink> make_drink(const string& name) {
auto drink = hot_factories[name]->make();
drink->prepare(200); // oops!
return drink;
}
};

这种写法避免了简单工厂模式冗长的switch case,会初始化所有的工厂,通过map来调用特殊类的工厂。

Functional Factory

class DrinkWithVolumeFactory
{
map<string, function<unique_ptr<HotDrink>()>> factories;
public:
DrinkWithVolumeFactory() {
factories["tea"] = [] {
auto tea = make_unique<Tea>(); tea->prepare(200);
return tea;
};
}
inline unique_ptr<HotDrink> DrinkWithVolumeFactory::make_drink(const string& name) {
return factories[name]();
}
};

这种工厂使用了lambda+function,存储了每个name对应的构建方法。不用再继承很多的派生工厂,看起来非常优雅。

tips:

boost::archive::text_oarchive 可以通过stringstream的方式序列化一个类,很方便


Singleton

Old style(double check lock)

class Database {
// same members as before, but then...
static Database& instance();
private:
static boost::atomic<Database*> instance;
static boost::mutex mtx;
};
Database& Database::instance() {
Database* db = instance.load(boost::memory_order_consume);
if (!db) {
boost::mutex::scoped_lock lock(mtx);
db = instance.load(boost::memory_order_consume);
if (!db) {
db = new Database();
instance.store(db, boost::memory_order_release);
}
}
}

C++11

class Database{
protected:
Database();
public:
static Database& get() {
static Database database;
return database;
}
//如果不从静态区分配内存,而是从堆上分配
static Database& get() {
static Database* database = new Database();
return *database;
}
Database(Database const&) = delete;
Database(Database&&) = delete;
Database& operator=(Database const&) = delete;
Database& operator=(Database &&) = delete;
}

Builder

这个模式实际使用起来比较常见,有个使用方式比较有趣,这里列出来

class PersonAddressBuilder : public PersonBuilderBase {
typedef PersonAddressBuilder self;
public:
explicit PersonAddressBuilder(Person& person) : PersonBuilderBase{ person } {}
self& at(std::string street_address){
person.street_address = street_address;
return *this;
} self& with_postcode(std::string post_code) { ... }
self& in(std::string city) { ... }
}; //使用,赋值属性后返回引用可以持续进行属性赋值
Person p = Person::create()
.lives().at("123 London Road")
.with_postcode("SW1 1GB")
.in("London")
.works().at("PragmaSoft")
.as_a("Consultant")
.earning(10e6);

DesignPattern-part1的更多相关文章

  1. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...

  2. Linux平台 Oracle 11gR2 RAC安装Part1:准备工作

    一.实施前期准备工作 1.1 服务器安装操作系统 1.2 Oracle安装介质 1.3 共享存储规划 1.4 网络规范分配 二.安装前期准备工作 2.1 各节点系统时间校对 2.2 各节点关闭防火墙和 ...

  3. Hadoop入门学习笔记---part1

    随着毕业设计的进行,大学四年正式进入尾声.任你玩四年的大学的最后一次作业最后在激烈的选题中尘埃落定.无论选择了怎样的选题,无论最后的结果是怎样的,对于大学里面的这最后一份作业,也希望自己能够尽心尽力, ...

  4. 薛非《品悟C-抛弃C程序设计中的谬误与恶习》读后感part1【转】

    薛非<品悟C-抛弃C程序设计中的谬误与恶习>读后感part1 作者:宝贝孙秀楠﹣大连程序员 发表于2012年10月5日由admin 出处:http://sunxiunan.com/?p=2 ...

  5. 小课堂Week12 Clean Code Part1

    小课堂Week12 Clean Code Part1 今天的主题是函数,让我们看一个函数,找一找其中的"不整洁". 我们也根据这段代码,讨论下对于整洁代码的两个重要原则. publ ...

  6. 实战Django:简易博客Part1

    舍得学习新技能的时候,通常不喜欢傻读书--捧着一本阐述该项技能的书籍,然后傻看,一路看下来,脑子里塞满了新的概念.知识点,头是越来越大,但技能却几乎没掌握半分. 多年来,舍得养成了用做实例来学习新技能 ...

  7. 实战Django:官方实例Part1

    [写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心 ...

  8. K2 Blackpearl开发技术要点(Part1)

    转:http://www.cnblogs.com/dannyli/archive/2012/09/14/2685260.html K2 Blackpearl开发技术要点(Part1) 预知后事如何,请 ...

  9. 小课堂Week8 例外处理设计的逆袭Part1

    小课堂Week8 例外处理设计的逆袭Part1 今天和大家讲一本书,书名是<例外处理设计的逆袭>. 为什么想讲这本书,是因为,例外处理在程序代码中到处存在,但是这些到底该如何写好,总觉得有 ...

  10. Asp.Net Design Pattern Studynotes -- Part1

    Asp.Net Design Pattern Studynotes -- Part1 let's start with an exampleto entry amazing OO world ! le ...

随机推荐

  1. go语言中实现生产者-消费者模式有哪些方法呢

    1. 简介 本文将介绍在 Go 语言中实现生产者消费者模式的多种方法,并重点探讨了通道.条件变量的适用场景和优缺点.我们将深入讨论这些方法的特点,以帮助开发者根据应用程序需求选择最适合的方式.通过灵活 ...

  2. Galaxy 生信平台(二):生产环境部署

    在 上一篇文章中,我们介绍了适合单个用户进行使用和开发的 Galaxy 在线平台,今天我们来聊一下在为多用户生产环境设置 Galaxy 时,我们应采取的一些可以让 Galaxy 获得最佳性能的额外步骤 ...

  3. 「学习笔记」DP 学习笔记1

    序列 DP 一般序列 DP 核心思想:将序列的前 \(i\) 个数的状态用一个更简单的形式表示出,并且体现出这些状态对后续的影响. 题目 ABC 267D 给定一个序列 \(a\),找到一个长度为 \ ...

  4. Pinot2的无人机任务和数据处理实践

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 4. 应用示例与代码实现讲解 4.1 应用场景介绍 4.2 应用实例分析 ...

  5. Linux下日志管理工具Logrotate

    背景: 项目上的Nginx和Tomcat已经跑了大半年了,Nginx的access.log和error.log将近1G大小:Tomcat下的catalina.out日志经常跑到打不出日志然后进行手动移 ...

  6. 开发中MongoDB遇到的各种问题

    目录 一.安装6版本以下 二.安装6版本及以上 三.安装6版本以下(解压版) 四.配置本地 Windows MongoGB 服务 五.navicat 连接远程mongodb数据库 六.ip不一致问题 ...

  7. range嵌套range beego前端页面渲染

    range嵌套range beego前端页面渲染 问题 listA(name,age...) listB(hobby...) 有多个不同的list 对象,在前端中需要用range渲染,但是多个list ...

  8. 从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生

    摘要:随着云计算的兴起和渗透,云数仓成为了数仓技术演进的新阶段,并且逐渐成为了众多企业的共同选择. 本文分享自华为云社区<从GaussDB(DWS)的技术演进,看数据仓库的积淀与新生>,作 ...

  9. 【Linq】 join 子句中其中一个表达式的类型不正确。在对“GroupJoin”的调用中,类型推理失败。

    报错代码: 原因分析:on后面的两个关联条件 数据类型不匹配,调整为一致即可.

  10. hexo博客Yilia主题首页菜单中文乱码解决方案

    方案一: 菜单设置成中文显示,编辑博客根目录下的_config.yml文件 设置language字段如下: language: zh-Hans 或者 language: zh-CN 取决于你的主题th ...