内存泄露检测神器 作者: nbboy 时间: 2020-08-05 分类: 软件架构,软件工程 评论 ###Summary 用非GC语言比如c/c++写程序的时候,内存泄露是非常让人头疼的,一个服务运行一段时间后莫名下线。在测试环境,我们有很多检测内存的方法,valgrind就是一个很犀利的工具。今天花了一点时间学习,最常用的就是检测内存泄露,命令也很简单: ```shell valgrind --tool=memcheck --leak-check=full ./program_name ``` ###Refs [Linux下几款C++程序中的内存泄露检查工具](https://blog.csdn.net/u012662731/article/details/78652651 "Linux下几款C++程序中的内存泄露检查工具") [内存泄漏检测工具valgrind神器](https://zhuanlan.zhihu.com/p/75416381 "内存泄漏检测工具valgrind神器")
设计模式之外观模式(二) 作者: nbboy 时间: 2019-08-11 分类: 软件架构,软件工程,设计模式 评论 ###简介 外观模式主要解决封装复杂逻辑的问题,也一定程度封装了变化的部分,对外提供一致的接口。具体实际中也用的比较多,比如Laravel框架中就用到外观模式去封装服务容器中底层类的 「静态代理」。我一般用在三方系统的接口封装上,比如三方接口封装不合理或者过于复杂,我就会用外观模式封装然后提供给内部系统使用。思想很简单,不多介绍了。 ###结构图和源码 借用一张图来表示下:  可以看到左边是复杂的具体实现类,右边下面就是外观类,其封装了左边的实现类。 具体实现可以看我的代码[study_design_pattern](https://github.com/x-debug/study_design_pattern "study_design_pattern"),在facade包下。
设计模式之简单工厂模式(一) 作者: nbboy 时间: 2019-06-07 分类: 软件架构,软件工程,设计模式 评论 ###简介 简单工厂模式就是用一个工厂函数封装具体的对象初始化过程,通过参数来控制需要具体初始化的对象。这里不容易变的部分是接口定义部分,比如例子中的Shape部分,容易变的部分是Rectangle,Circle等这些实现,要扩展的时候,根据需求增加不同的实现就可以做到无限扩展。 ###结构图与代码 用图表示大概是这样的:  可以看到,客户端在使用的时候,只需要调用工厂函数就可以创建具体实现,其依赖的也是接口。这就是针对接口去编程,而不是具体实现。 具体实现可以看我的代码[study_design_pattern](https://github.com/x-debug/study_design_pattern "study_design_pattern"),在simple_factory包下。
领域驱动设计漫谈(1) 作者: nbboy 时间: 2019-05-30 分类: 软件架构 评论 ## 前言 随着微服务的兴起,DDD领域驱动设计又开始被很多人提起来。最近,我也在了解这方面的知识,所以对软件设计方法做一个简单总结,但是相关书还没全部看完,可能理解不深刻,等看完再做一个总结。 ## 问题 先说下在没有经过领域驱动设计时软件设计方法,也就是我们平时使用的数据库驱动设计方法。当接到部门领导提的需求,或者产品经理的文案,先开始脑子里想程序如何设计,一般程序员先定义表结构,考虑表结构细节,然后这个过程中根据产品需求,不断将设计靠近需求。这种设计方法当然没有任何问题,只要程序员经验足够丰富,往往也能收到不错的效果。在业务初期,我们的功能大都非常简单,普通的CRUD就能满足,此时系统是清晰的。随着迭代的不断演化,业务逻辑变得越来越复杂,我们的系统也越来越冗杂。可以想象,一个跨越6,7年,前后程序员换了3,4批的项目,可能业务方说需要加一个简单的需求,但是可能由于改动非常多,做起来痛苦不堪;或者改一处必须导致全部相关的UserCase都得重新通过测试。 还记得我刚入行WEB程序的时候(因为之前是做游戏开发的),对通过表结构思考程序设计很不习惯。我更喜欢从OO角度思考问题,我当时甚至这样想,难道WEB程序不能OO设计么?看到很多同事所谓的对象化,也只是带过程化的对象,很不习惯,不自然,用DDD作者的话说就是贫血模型或者说失血模型。这种设计,往往随着业务复杂,人员变更,程序越来越让你难以理解,模块依赖性紊乱,模块层次错杂,原来应该写在核心层的业务逻辑却被写在控制器层。就如下面这幅图一样:  ## DDD的关键元素 ### 战略建模 战略和战术设计是站在DDD的角度进行划分。战略设计侧重于高层次、宏观上去划分和集成限界上下文,而战术设计则关注更具体使用建模工具来细化上下文。那如何进行战略建模呢?现实世界中,领域包含了问题域和解系统。一般认为软件是对现实世界的部分模拟。在DDD中,解系统可以映射为一个个限界上下文,限界上下文就是软件对于问题域的一个特定的、有限的解决方案。 这里引出了限界上下文的概念,那什么是限界上下文呢?概况起来说:**一个由显示边界限定的特定职责。领域模型便存在于这个边界之内。在边界内,每一个模型概念,包括它的属性和操作,都具有特殊的含义。**不过,这个定义很官方,我的理解就是软件设计中模块的概念,比如订单子域是一个模块,商品子域又是另外一个模块。为什么要模块的封装概念?从软件设计上我们应该能很好理解,把系统分成由更多子系统显然比一个大系统更加好管控。从微服务拆分角度说,一个微服务进程就是一个限界上下文,也往往可能是大公司里的一个小团队负责。模块的拆分是一个问题,另外一个问题是模块之间的联系,或者说模块与模块的沟通问题,比较幸运的是前人总结了这方面的经验: **限界上下文之间的映射关系** - 合作关系(Partnership):两个上下文紧密合作的关系,一荣俱荣,一损俱损。 - 共享内核(Shared Kernel):两个上下文依赖部分共享的模型。 - 客户方-供应方开发(Customer-Supplier Development):上下文之间有组织的上下游依赖。 - 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。 - 防腐层(Anticorruption Layer):一个上下文通过一些适配和转换与另一个上下文交互。 - 开放主机服务(Open Host Service):定义一种协议来让其他上下文来对本上下文进行访问。 - 发布语言(Published Language):通常与OHS一起使用,用于定义开放主机的协议。 - 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。 - 另谋他路(SeparateWay):两个完全没有任何联系的上下文。 ### 战术建模 梳理清楚上下文之间的关系后,我们需要从战术层面上剖析上下文内部的组织关系。首先看下DDD中的一些定义。 ##### 实体 当一个对象由其标识(而不是属性)区分时,这种对象称为实体(Entity)。 ##### 值对象 当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象(Value Object)。 ##### 聚合根 Aggregate(聚合)是一组相关对象的集合,作为一个整体被外界访问,聚合根(Aggregate Root)是这个聚合的根节点。 聚合根这个概念稍微解释下,听起来其实很抽象,我自己的理解是把几个逻辑上相关的对象(实体/值对象)有意的组织在一起,并且对外只提供根实体的访问,内部维护状态的一致性。 ##### 领域服务 一些重要的领域行为或操作,可以归类为领域服务。它既不是实体,也不是值对象的范畴。 ##### 领域事件 领域事件是对领域内发生的活动进行的建模。 ## 实践DDD 未实现 ## 总结 DDD驱动设计思想作为一种领域建模的设计思想指导我们进行灵活设计,让我们的系统更加有弹性和充血。这个过程当然不是通过前期的一次设计就能完成的,而是通过不断和领域专家沟通,并且同步领域模型和代码模型,重构之前的不合理部分代码,然后才能达到合理的设计。