Cpp 设计模式笔记——3. 结构型模式
Adapter (适配器) 适配器模式是一种结构型设计模式,它使接口不兼容的对象能够相互合作。 假设我们已有一个现有类Adaptee,它提供接口specificRequest(),客户端希望调用接口类Target的request()方法,两个接口无法直接相连,并且可能存在一些差异,例如函数参数顺序。 出于某些原因,我们无法更改旧有代码,那么可以选择在其中加上适配器Adapter: 适配器Adapter直接继承接口类Target,可以对客户端提供request()方法; 适配器Adapter将现有类Adaptee作为数据成员,在request()方法中实际调用Adaptee对象的specificRequest(),在传递过程中还需要处理一些差异,例如调整函数参数顺序。 示例代码如下 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748#include <iostream>#include <memory>#include <u...
Cpp 设计模式笔记——2. 创建型模式
Factory Method (工厂方法) 工厂方法模式是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。 我们需要定义两个抽象类:产品基类Product和工厂基类Factory,后者提供创建产品的方法createProduct()。具体产品(ProductA、ProductB)需要继承自产品基类Product。每一个产品都需要提供配套的工厂(FactoryA、FactoryB),工厂需要继承自工厂基类Factory,对创建产品的方法提供不同的实现。 示例代码如下 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556#include <iostream>#include <memory>// 产品接口struct Product { virtual void describe() const = 0; virtual ~Product() = d...
Cpp 设计模式笔记——1. 概述
有必要学一下设计模式,虽然在大部分情况下都是基于Java语言来讨论设计模式,但是面向对象的思想对于各种语言都是通用的,这一系列笔记将使用C++进行讨论。 设计原则通常设计模式遵循七个基本原则,如下文所示。有的教程中只有六个基本原则,不含单一职责原则。 单一职责原则 每个类应该只有一个职责,即该类只有一个引起变化的原因。 这样可以减少类之间的耦合,提高系统的可维护性。 与单一职责原则相违背的极端做法是使用上帝对象,它负责了太多的职责,了解了太多的信息,这会导致代码的修改和维护非常困难。 考虑一个情景,我们需要实现一个简单的文件管理类:读取文件内容并输出到控制台,向文件中写入指定内容,我们希望在读写操作的同时在控制台中输出日志。 不符合单一职责原则的例子如下 123456789101112131415161718192021222324252627282930313233343536373839#include <fstream>#include <iostream>#include <string>class FileManager ...
Fish Shell 配置笔记
记录一下关于fish的使用和配置。 概述fish和zsh是最常见的两种用于替代默认bash的现代shell,两者的定位有点区别: fish对用户友好,开箱即用,不需要复杂配置,缺点是语法与bash不兼容; zsh兼容bash的语法,缺点是必须进行较复杂的配置,否则和bash使用体验差不多。 对这些shell的主题配置,通常都会基于oh-my-zsh、oh-my-fish以及pwsh的oh-my-pwsh这些美化工具进行,但是鉴于fish的开箱即用特点,我决定不使用美化工具,默认的就可以了。 由于fish不兼容bash的语法,因此通常不建议将其作为默认shell使用,而是在登陆后手动开启fish 1fish 这样我们可以继续使用bash的.bashrc进行环境变量等配置,fish也会自动继承相应的配置。日常操作中最好也是继续使用bash脚本,通过shebang的方式指定使用bash。 使用fish默认支持实时更新的彩色显示,对于无效命令使用红色进行警告,有效命令则显示为蓝色,对于有效路径会显示下划线提示。(这些默认行为都可以通过配置修改) fish会自动给出命令提示,以灰色显...
什么是高质量的代码?
学习并整理一下个人的理解:什么样的代码是高质量的代码? 代码的评价指标这部分内容主要参考知乎上的回答:什么样的代码是高质量的代码? - 王争的回答 - 知乎。 简洁性 KISS原则:“Keep It Simple,Stupid” 我们需要通过尽可能简单的代码来完成目标,避免炫技地引入复杂的结构和设计模式。 典型的反例就是Java,完全的面向对象导致了代码架构的过度复杂化。例如程序员需要点一杯咖啡,Java 风格的代码如下 12345CoffeeFactoryBuilderSingletonManagerProvider.getCoffeeFactoryBuilderSingleton() .getCoffeeBuilder() .addMilk() .addSugar() ...
MATLAB 绘图笔记
这里主要关注 MATLAB 绘图的技术性内容,不讨论非技术性内容,例如论文中的绘图要求或偏好。 MATLAB 的语法学习曲线很特别:入门时用起来特别简单舒服,但是深入学下去就会感觉到语法非常混乱,无所适从。尤其在绘图部分,MATLAB 杂揉了命令式语句和面向对象的语句,存在太多的语法糖,毫无逻辑性可言。因此在这里记录一些关于绘图的代码,便于查找。 MATLAB 同时提供面向过程和面向对象(指定操作的 figure 或 ax)的绘图语法,面向过程的语法通过会直接获取当前 figure 或 axes 进行操作,面向对象的语法通常是在面向过程对应函数的第一个参数中传递 figure 或 axes。 需要说明的是,下文中的一些代码写法和常见的教程不太一样,包括: 将常见的命令语法都换成了可读性更高的函数语法,例如 hold on 换成 hold('on'),参考官方文档中的 选择命令语法或函数语法; 将早期的键值对语法换成了更简洁的形式,例如 plot(ax, x, 'DisplayName', 'energy'); 改成 plot(...
Git 使用规范
分支规范分支的命名习惯上使用小写字母、数字、连字符 - 以及斜杠 / 组成。这里建议使用斜杠 / 因为它会被Git自动识别,并且在 .git/ 中为其创建目录结构,例如 .git/refs/heads/feature/xxx。 复杂项目对于使用多个平行分支进行版本管理的复杂项目,分支的命名和使用通常遵循如下规范: 两个长期分支: 主分支:包括项目的所有正式版本,名称为 main 或 master; 开发分支:包括项目的最新版本,名称为 develop、dev 或 next; 几种短期分支:(向长期分支合并完成后即可删除) 功能分支:拆分为多个独立功能进行同步开发,名称例如 feature/login-page,feature/user_module; 预发布分支:在正式版本发布之前的准备,名称例如 release/xxx,xxx 代表日期;(改为 pre-release 可能更合适) 快速修复分支:名称例如 hotfix/xxx,xxx 代表修复的问题编号或描述。 关于长期分支的使用: 主分支和开发分支作为一组平行线长期存在; 主分支上的结点主要是发布的稳定版本,在...
Python 命令行参数解析 argparse
Python经常被用来写一下简化操作的脚本,并且要求脚本支持一定的选项,有必要整理一下Python命令行参数解析的用法。 Python自带的argparse模块功能已经非常强大,使用非常便捷。Python其实还有另外两个模块可以完成同样的任务:getopt和optparse,但是前者过于简单,后者已经被弃用,目前只推荐使用argparse。 与之形成鲜明对比的是,C/C++对这种基础的需求通常都是直接手写的,或者去下载一些第三方提供的纯头文件库,为这种简单的任务引入外部依赖其实也并不合算,不如直接自己写了。 极简例子从最简单的例子开始 test.py123import argparseparser = argparse.ArgumentParser()parser.parse_args() 这两行的含义为:设置一个参数解析器,解析参数。 直接运行脚本,无事发生 1python test.py 空的参数解析器为我们提供了--help(-h)参数,可以打印使用帮助,例如 1python test.py -h 输出形如 1234usage: test.py [-h]...
MATLAB 工程化编程笔记
MATLAB 被吐槽的一个重要原因就是大量 MATLAB 代码的质量一言难尽:完全脚本式编程、命名随意、结构松散、缺乏代码格式化、缺乏注释和单元测试。这类代码虽然能完成一次性的计算,却难以复现、扩展或维护,注定变成屎山代码。 本文关注如何让 MATLAB 代码变得工程化,使得 MATLAB 项目开发更有条理、更容易维护,具体包括输入参数检查、代码注释,单元测试等主题。 其实还应该加上日志系统,但是 MATLAB 并没有官方提供的,或者第三方广泛使用的日志系统。 函数参数检查为了得到健壮的代码,非常有必要对函数的参数进行检查,除了最基础的参数个数,还需要关注参数的类型和数据范围等,下面介绍几个MATLAB提供的用于参数检查的内置函数。 assert + isXXX最简单的做法就是基于 assert 和 isXXX 检查函数的形参是否满足要求,例如 1234567891011function func(u, t, f, n, b, flag, params) assert(isnumeric(u) && (isvector(u) || ismatrix(u)...
MATLAB 面向对象学习笔记
随着代码越来越复杂,我实在是无法忍受修改完全面向过程的混乱程序了,急需引入面向对象的语法进行重构。 笔记主要参考的是《MATLAB 面向对象编程——从入门到设计模式》(徐潇,李远),书中使用的估计是 2015 左右的版本。 MATLAB 的面向对象语法从整体上看,既不像 C++ 和 java 那样严格,也不像 Python 那样过于灵活,而是具有自身的特点。 虽然面向对象机制不可避免地会带来一些运算效率的损失,但是我认为这是值得的,只是需要避免在涉及大量计算的性能瓶颈中使用面向对象,对于程序中的辅助部分,使用面向对象所带来的代码简化还是非常舒服的。 简单示例从最简单的一个自定义类型开始 point2d.m1234567891011121314151617181920212223242526classdef point2d properties x y end methods function obj = point2d(x0,y0) if nargin == 0 obj...
