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. XTU OJ 程设训练 1407 Alice and Bob

    题目描述 Alice和Bob打球,已知他们打过的每一回合的输赢情况,每个回合获胜的一方可以得一分. Alice可以随意设定赢得一局比赛所需的分数和赢得整个比赛所需要的局数. Alice想赢得比赛,请问 ...

  2. nc工具利用

    c: 瑞士军刀/网络测评工具    将本地的cmd 权限移交到外网 nc工具:应用    本地cmd打开, 输入  nc -e cmd 远程ip  5577  #连接到远程ip的5577 远程cmd打 ...

  3. Python基础 - 逻辑运算符

    Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20: 运算符 逻辑表达式 描述 实例 and x and y 布尔"与" - 如果 x 为 False,x a ...

  4. MAUI Android 关联文件类型

    实现效果 打开某个文件,后缀是自己想要的类型,在弹出的窗口(用其它应用打开)的列表中显示自己的应用图标 点击后可以获得文件信息以便于后续的操作 实现步骤 以注册.bin后缀为例,新建一个MAUI项目 ...

  5. 手摸手带你 在Windows系统中安装Istio

    Istio简介 通过负载均衡.服务间的身份验证.监控等方法,Istio 可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少更改甚至无需更改. 通过在整个环境中部署一个特殊的 sidecar ...

  6. Vue3 之 响应式 API reactive、 effect源码,详细注释

    Vue3之响应式 API reactive. effect源码,详细注释 目录 一.实现响应式 API:reactive.shallowReactive.readonly.shallowReadonl ...

  7. Volo.Abp升级小记(二)创建全新微服务模块

    @ 目录 创建模块 领域层 应用层 数据库和仓储 控制器 配置微服务 测试微服务 微服务注册 添加资源配置 配置网关 运行项目 假设有一个按照官方sample搭建的微服务项目,并安装好了abp-cli ...

  8. 1. Mybatis 简介

    1. Mybatis历史 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code.随着 ...

  9. 一次oracle行级锁导致的问题

    分析问题:我在plsql/developer是用的system用户连接的数据库,而在crt用  sqlplus / as  sysdba 连接数据库,是sys用户.现在在plsql/developer ...

  10. 微信小程序 - 视图与逻辑

    [黑马程序员前端微信小程序开发教程,微信小程序从基础到发布全流程_企业级商城实战(含uni-app项目多端部署)] https://www.bilibili.com/video/BV1834y1676 ...