- 课程目标
- 面向对象设计原则
- 原则概述
- 可维护性
- 指的是软件可以很方便的理解、改正、适应和拓展的难易程度
- 就是方不方便修改了的意思
- 可复用性
- 指的是软件能被重复使用的难易程度
- 指导性原则
- 用于评价一个设计模式的使用效果的重要指标之一
- 为支持可维护性复用诞生
- 可维护性
- 单一职责原则
- 一个类制作一件事
- 作用
- 用于控制一个类的粒度
- 保证一个类里面不用实现所有的功能,仅仅需要实现单一职责即可
- 定义
- 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中
- 就一个类而言,应该仅有一个引起变化的原因
- 开闭原则
- 不修改源代码,只添加代码
- 定义
- 软件实体只能增加功能,尽量不修改功能
- 尽可能只是拓展代码来增加新功能/修改原有功能
- 关键
- 抽象化
- 具有稳定的抽象层+灵活的具体层
- 修改配置文件,增加类,这个些操作都符合开闭原则
- 里氏代换原则
- 父类对象可被子类对象代替,且程序将不会产生任何错误和异常(因为子类把父类的一些方法重载了)
- 在程序中尽可能使用基类类型来对对象进行定义
- 依赖倒转原则
- 编程使用配置文件,仅仅是接受对象操作对象,在外部进行创建对象注入
- 接口隔离原则(网络上的那种API接口)
- 一个接口尽可能做少的事情
- 把接口都拆开来
- 合成复用原则
- is-a继承复用 has-a组合/聚合复用
- 就是类似于把mysql的obj反射出来,然后再操作
- 迪米特原则
- 减少对象之间的交互
- 两个对象不应该发生任何直接的相互作用
- 通过”第三者”转发这个调用
- 引入一个合理的”第三者”来降低现有对象之间的耦合度
分类: 笔记
[笔记] 设计模式: 统一建模语言
第一章
- 课程目标
- 统一建模语言
- UML
- 统一建模语言
- 概念
- 通用的可视化建模语言
- 通过一些标准的图形符号和文字对系统进行建模
- 作用
- 对于软件进行描述、可视化处理、构建软件系统的文档
- 视图(View)
- 用户视图
- 以用户的观点来标识系统的目标,它是所有视图的核心
- 描述系统的需求
- 结构视图
- 表示系统的静态行为
- 描述系统的静态元素,如包、类与对象,以及它们之间的关系
- 行为视图
- 表示系统的动态行为
- 描述系统的组成元素如对象在系统运行时的交互关系
- 实现视图
- 表示系统中逻辑元素的分布
- 描述系统中的文件以及它们之间的关系
- 环境视图
- 表示系统中物理元素的分布
- 描述系统中的硬件设备以及它们之间的关系
- 视图关系图
- 用户视图

- 图(Diagram)
- 用例图
- 类图
- …
- 模型元素(Model)
- 模型元素
- 就是图上面的符号
- 用于描述事物以及事物与事物之间的关系
- 每一个模型元素都要一个阈值相对应的图形元素
- 同一个模型元素可以在不同的UML图中使用
- 模型元素
- 类
- 定义
- 封装了数据和行为
- 是具有相同属性、操作、关系的对象集合的总称
- 一个类可以有多个职责(功能),但设计的好的类通常只有单一职责(功能)
- 类的属性
- 类的数据职责
- 类的操作(类实现的方法)
- 类的行为职责
- 定义
- 类图
- 用来描述不同的类以及它们之间的关系
- UML类图
- 类名

- 类的属性

- 类的操作(其实就是类实现的方法)

- 类之间的关系
- 关联关系
- 表示一类对象与另一类对象之间的关系
- 实线连接
- 通常将一个类的对象作为另外一个类的成员变量
- 单向关联
- 关联关系

- 双向关联(就是两个类互相作为对方的成员属性)

- 自关联(就是自己的成员属性存储了一个自身的对象)
- 多重性关联(就是有2个+的成员变量存储/被存储了)
- 多重表示,通常在直线上使用一个数字/数字范围来表示

- 图例

- 聚合关系
- 表示整体与部分的关系(容器与成员的关系)
- 成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在
- 使用带空心菱形的直线表示
- 图例

- 组合关系
- 聚合关系相同的表示
- 成员是整体的一部分,但是成员对象跟整体对象的生命周期一样,整体对象销毁了,成员对象也会被销毁
- 使用带实心的菱形直线表示
- 因为是在整体(Head)对象中new的对象,销毁了head,就会连带把成员对象都销毁掉

- 依赖关系
- 表示一个事物使用另外一个事物
- 体现在某个类的方法使用另一个累的对象作为参数
- 使用带箭头的虚线
- 依赖的一方指向被依赖的一方

- 三种实现方法

- 泛化关系(继承关系)
- 用于描述父类与子类的关系
- 用带空心三角形的直线表示
- 图例

- 接口与实现关系
- 接口之间也存在继承关系和依赖关系
- 接口与雷志坚存在一种实现的方法
- 使用带空心三角形的虚线表示
- 图例

- 拓展机制
- 注释
- 可以给类图(UML)增加注释
- 注释

[微信小程序] 开发心得
前言
最近开始学习ES6的语法,然后突然想到去年挖下来的小程序的坑还没有填完,就开始捣鼓起来了。接下来会分享一些我在这次开发过程中遇到的坑点和经验,由于小程序是微信发起来的,所以有很多问题都可以尝试在小程序的开发社区里面搜一下。
UI框架推荐
这次最蠢的一件事就是手莽课表,殊不知已经有前人开发出了插件。自己写CSS实在是痛苦。有一部分的UI也用了微信的WeUI,但其实还有更多选择:
通过这几个组件库可以快速构建小程序,不用花过多的时间在UI上,很适用于我们这些后端开发者。
SSL配置
如果你的小程序需要向你的服务器发起数据请求的话,就要留意这一点。小程序文档中要求你的后端接口的网址必须满足以下两点:
- HTTPS
- 已经备案
无论你的主机在哪都要给你的域名备案,不然真机模拟的时候就永远都无法请求,会报图1.1的问题。

如果你的证书已经备案了,还是报这种错误的话,那就是你的接口缺少了证书。一般tx云或者阿里云的免费证书就够用了,直接申请就可以。
如果还是报错,那就是缺失了中间证书。具体体现就是你的浏览器可以直接访问,并且确实走的是HTTPS,但就是无法请求,你可以通过这个网址:https://www.myssl.cn/tools/check-server-cert.html检测是否缺失中间证书。一般是需要把root和domain name的证书打包在一起才行,就是用.pem和.key后缀的文件作为证书文件绑定到你的Http服务器上。
JS平台差异
这个点主要是出现在Date对象上面
//Android平台上这么写将会正常返回对象 let obj = new Date("2020-02-27"); obj.getDay(); //IOS平台只支持用"/"来分割时间 let obj = new Date("2020/02/27") //如果你使用"-"来创建对象的话,ios将会返回null
这个是我目前认为小程序最为诟病的一个问题。就是多平台JS不通用。小程序的本质上还是VUE,样式基本上没啥问题,但js出现了bug就真的特别难复现,这个bug甚至在控制台中是无法找到的,实在是恶心,希望微信会尽快修好。
结尾
其实小程序是一个很好的分发平台,但是太多毛刺会减弱大家的开发积极性,希望以后会越做越好。也希望能帮到你,Peace
JavaScript OOP笔记[ES3]
简介
最近开始要学习ES6了,翻出JS看了看,发现OOP部分还没有掌握,所以就赶紧进行了补课。下面是这次学习的一些,个人认为重要的知识点。
对象
每次使用JavaScript的构造器时,都会创建一个对象。一个初始化的对象中将会含有一个属性集,称之为prototype(对象属性),还有一个constructor(构造器)。而属性集里面中则会默认存在一个属性_proto_(原型)。这个属性存储的是父类的prototype(可以理解为指向父类的一个指针)。
对象属性
访问对象属性
对象.prototype.属性名
创建对象属性
对象.prototype.属性名 = 值
继承
JavaScript中实现继承主要是通过修改对象的_proto_(原型)指向到父原型来实现的继承。一旦理解了就会很简单,但是这个设计真的不好,而且原型这个称谓真的太容易混淆了。
注意!
//错误的继承 student.prototype = person.prototype;
解释:因为如果是这么赋值的话,在后续的操作中,比如给student增加属性或者方法时,收student的本质还是person,这样子修改的话,本质上还是修改的person的对象属性。
//正确的继承 student.prototype = Object.create(person.prototype) //此时就可以正确把student的_proto_正确的指向person.prototype了
(JavaScript在ES6中貌似已经引入了extend应该能改善当前这个反人类的设计了)
原型
原型就是对象上一个存储父类的属性,称之为_proto_。由于Object是顶层对象,所以它的原型就是NULL。
原型链
bosn的原型指向Student,Student的原型又会指向Person,Person的原型又会指向Object,则称这条联系为原型链。
InstanceOf
该方法用于判断方法右边的函数是否存在于左边对象的原型链中,返回一个Bool值。其原理还是通过遍历prototype来看看左边的原型链上面是否存在右边函数的prototype。
用途:判断对象是否存在该方法(函数)
尾言
说实话,平时对于JavaScript的应用还停留在普通的事件应用,函数闭包这种层面,第一次了解了关于JS的面对象过程,也是受益匪浅,希望可以帮助到后续的ES6的学习,如果你觉着这篇文章好的话,不妨点一个赞吧,如果我理解有错误,也欢迎在下方评论区中学习交流owo。
探究php的MD5函数输出的原始二进制数据是啥?
前序
最近我的朋友(Ge15emium)在研究CTF,发给我一个关于使用MD5函数实现sql注入的博文。文章通过构造特殊的字符串通过md5函数输出后,可以构造成注入SQL,拿到Flag。
博文链接:http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/?tdsourcetag=s_pcqq_aiomsg
通过文章我们知道作者通过使用md5()对ffifdyop进行加密处理后可以构造出‘or’6<trash>这样一个字符串,来规避掉php的代码检查,进而获得Flag。
本文主要探究的是md5函数怎么把32位16进制的报文摘要输出成为目标字符串,不涉及CTF的解密流程以及MD5的加密流程
1.怎么对字符串进行的加密?
php的md5()具有输出原始二进制数据的特性。
通过文章我们得知,博主通过使用php的md5(“ffifdyop”,true)输出其加密后的原始二进制数据得到目标字符串。从这个流程中我们进而引出下一个问题原始二进制数据是啥?怎么来的?
2.原始二进制数据是啥?怎么来的?
原始二进制数据不是指100111这些二进制数据,而是原始字符串转换成ascii码后组成的字符串。
接下来就使用前序中所说的字符串来演示如何转换。
- 使用md5(“ffifdyop”)进行加密
通过加密后将会得到之后的32位16进制字符串:276f722736c95d99e921722cf9ed621c - 将32位16进制字符串按照2个字符为一组切割成为16组16进制的字符串
切割成27,6f,72,27,36,c9,5d,99,e9,21,72,2c,f9,ed,62,1c - 将每一组16进制的数值转换成2进制
100111,1101111,1110010,100111,110110,11001001,1011101,10011001,11101001,100001,1110010,101100,11111001,11101101,1100010,11100 - 将每一组2进制数值转换称为10进制数值
39,111,114,39,54,201,93,153,233,33,114,44,249,237,98,28 - 最后对照如下的ASCII码表即可翻译的出最终的原始二进制字符串
以前四组为例39=>’,111=>o,114=>r,39=>’,最终的组成’or’这一个字符串
(其实理论上我们可以直接把16进制转换成10进制就好了,但是此处是为了展示我的思考过程才会有2进制这一步,希望写细一点可以帮助大家的理解和认识)
结尾
CTF的注入玩法真的是神仙玩法,平常使用md5函数都还没思考过这个问题,借由此机会也提升了我的php基础知识,使其更加扎实可靠,作为2020第一篇原创文,希望日后也能多写一些这样的文章吧。
[笔记][翻译] 在Windows上编译PHP拓展
- 来自于 Benoit Blanchon 20 January 2015
- 译者 7gugu
- 原文章链接 https://blog.benoitblanchon.fr/build-php-extension-on-windows/
我最近尝试编写了一个PHP拓展,虽然说文档上有很详细的介绍如何在Linux上进行编译操作,但是关于在Windows平台上编译的信息少之又少。
所以这篇文章就是给大家介绍一下,如何使用Visual Studio构建一个PHP拓展。
环境要求
这篇指南是假设在你已经编写了链接所示的一个输出”Hello World”的PHP拓展。 here并且你已经在Linux上成功编译了。
在Windows上构建你的PHP拓展前,你需要完成以下的操作。
- Visual Studio
(这里是一个坑点,请确认你的VS的编译器的版本跟PHP编译时的版本是一样的。比如说官网的7.1.33是用的VC14【VS2015】编译的,那么你的拓展也要是用VC14编译的,否则是不能安装你编译好的拓展的。如果你用的是VS2017+,但你有用的是旧版本的PHP环境写的拓展,那么你就要手动编译PHP才能使用你编写的拓展了) - PHP源代码 (未编译的PHP代码)
在之后的文章中,我将会按一下列表假设:
- PHP源码是位于
C:\php-src
- 你编写的”Hello World”拓展位于
C:\MyPhpExtensions\hello
在Windows上编译拓展跟Linux上有点相似
你应该已经很熟悉这个过程,但这里还是列出了一个步骤清单给你:
(以下虽然是在Linux上构建编译时运行的代码,但是在Windows上其实是一样的,只是有一些指令的名字和运行方法有点不同而已)
- 安装
php-devel
包 - 运行
phpize
从config.m4
中生成configure
脚本 . - 运行
./configure --enable-hello
生成Makefile
- 运行
make
开始编译拓展
(以下是在Windows上编译时要改变的东西,按步骤执行就可以顺利生成拓展了)
使用 config.w32
替代 config.m4
在Windows平台上, 使用config.w32
代替config.m4
,但是格式上还是有点不同。
从 config.m4
迁移到 config.w32
是非常直接的, 你仅仅需要的是把Automake的代码转换成JavaScript语法的代码。
下面是一个简单的例子:
ARG_ENABLE("hello", "Hello World support", "no");
if (PHP_HELLO != "no") {
EXTENSION("hello", "php_hello.c", true);
}
不要忘记把EXTENSION
的第三参数设置成true
, 这么设定就会选择生成动态编译库(DLL)而不是静态编译到PHP代码中。
如果你想知道更多关于*.32的语法信息,你可以看看别的文件夹的*.w32文件。
使用 buildconf.bat
代替 phpize
在Windows平台上,你将会使用 buildconf.bat
代替 phpize
。
打开VS的”适用于 VS 20XX 的 x86/64 本机工具命令提示”命令行工具并且运行以下代码
cd C:\php-src
buildconf.bat --add-modules-dir=C:\MyPhpExtensions
buildconf.bat
将会自动扫描 C:\MyPhpExtensions
文件夹下所有的 config.w32
文件。
随后将会生成一个 configure.bat
的脚本文件.
使用 configure.bat
代替 ./configure
在Linux上,configure
就仅仅是用来编译拓展用的,但是在Windows平台上configure.bat
是用来编译PHP代码为exe文件的。
你需要在运行 configure.bat
时添加以下命令行选项以生成最少数量的内容,从而确保不必解决对外部库的依赖性
cd C:\php-src
configure.bat --disable-all --enable-cli --enable-hello
--disable-all
就是禁止生成其他内容,省略了输入 --disable-xxx
和 --without-xxx
的必要 , --enable-cli
是启用php命令行界面 (ie php.exe
) , --enable-hello
是启用编译你的拓展”Hello”
系统默认会按照TS(线程安全)模式进行编译,如果你需要NTS(线程非安全)模式进行编译,你仅仅需要加上这一条 --disable-zts
,就可以按照NTS模式进行编译。
使用 NMake
代替 Make
configure.bat
将会生成一个Windows版本的 Makefile
用作在Windows上 Make
.(编译代码)
开始编译代码,仅仅需要运行以下代码即可:
nmake
这不仅仅会编译你自己的拓展,同时也会将 php.exe
编译出来。 这对于开发者来说,是一个很方便的做法,因为你需要一个相同编译环境生成出来的 php.exe
,那样子才能正确安装你的PHP拓展。
实际上,为了加载到php中,您的扩展必须与php构建相匹配,条件是:
- 系统位数 (32 or 64 位)
- 线程是否安全 (TS 模式 或者 NTS 模式)
- 编译器的版本 (VS9, VS11 之类的.)
如果你确实不需要编译出 php.exe
, 那么你仅仅需要按以下代码运行即可:
nmake php_hello.dll
消除警告(Warnings)
在编译PHP拓展的过程中,编译器常常会报一堆警告:
如果你想禁用这些警告,你可以在 c:\php-src\win32\build\config.w32
中,加入以下的代码段:
ADD_FLAG('CFLAGS', ' /wd4005 /wd4267 /wd4244 ');
ADD_FLAG('CFLAGS_BD_ZEND', ' /wd4018 /wd4101 /wd4090 /wd4273 ');
ADD_FLAG('CFLAGS_BD_MAIN', ' /wd4018 /wd4090 ');
ADD_FLAG('CFLAGS_BD_MAIN_STREAMS', ' /wd4013 ');
DEFINE('RC', '$(RC) /nologo /d _USING_V110_SDK71_');
并且,在 C:\php-src\ext\standard\config.w32
中加入这行代码:
ADD_FLAG('CFLAGS_BD_EXT_STANDARD', ' /wd4047 /wd4018 ');
最后在 C:\php-src\sapi\cli\config.w32
中加入下列这一行代码:
ADD_FLAG('CFLAGS_BD_SAPI_CLI', ' /wd4018 ');
笔记: 一些能够帮助你开发PHP拓展的博文[英文生肉]
- Extension Writing Part I: Introduction to PHP and Zend
- Extension Writing Part II: Parameters, Arrays, and ZVALs
- [Extension Writing Part II: Parameters, Arrays, and ZVALs continued]
- Extension Writing Part III: Resources
- Wrapping C++ Classes in a PHP Extension
- PHP Extension Writing
- PHP Extensions Made Eldrich: Working with the API ÔÇô the PHP C API
- PHP Extensions Made Eldrich: Classes
- Build your own PHP on Windows
- PHP Internals Book
- Zend API: Hacking the Core of PHP
[笔记]qduoj 前端 二次开发总结
前言
接了学校一个SRP项目,所以最近一个月都开始搞这个OJ的前端开发,现在分享一些这个OJ部署的一些坑点,帮助大家避坑,也Mark下给自己做笔记用.
启动前端组件
git clone https://github.com/QingdaoU/OnlineJudgeFE.git
npm install
npm run build:dll
配置Config/index.js
npm run dev
FE即可成功编译
引入Component
- 创建Conponent VUE文件
- 配置route/route.js
- 配置views/index.js
- 参考iview语法设置导航栏入口
- 修改i18n的双语文件即可
通过上述步骤即可将自己的组件引入到FE之中
关于OJFE使用的CSS坑点
QDUOJ这个平台实际上时使用了两种UI框架
1. iView
2. ElementUI
其中iView是作为UI组件库使用,所以一开始Coding的时候会发现前端的语法与ElementUI对不上.而ElementUI的实际作用仅仅是给OJ提供了动画效果,所以为了让自己的组件也有弹出的效果,我们要使用Panel组件使得自定义的组件具有相同的弹出动画效果.
如果需要自定义动画效果的话,则需要我们自身使用transition标签来创建动画效果
结语
现在其实开刚刚起步,大致把前端摸了一下(后端也会摸,但我不是主要负责这块的),后续应该还有坑点.到时候也会分享出来给大家看的.
小声BB,QDU的文档真的不咋地.(可能是我菜才看不懂吧,若有冒犯请见谅:joy:)
[笔记]Git使用总结
导论
最近学校老师布置了”项目版本管理”,然后搞了一周,总结了一些协作的经验,写在这里,方便大家也方便日后的自己。
下载仓库的代码
- 访问网页仓库
- 获取SSH/HTTP链接
- cmd中输入以下指令
git clone 仓库地址
提交自己的代码到Git库
- 修改自己的代码
- 执行以下指令
git add * //把代码从工作区提交到缓存区 git commit -m "message" //添加代码备注 git push [--set-upstream origin branchname] //假如使用新的分支,就需要设定分支点[一般从master分支]
拉取更新到本地
- 如果master是自己控制的,执行以下代码即可
git pull
- 如果master是别人的,你只是一个贡献者,就需要执行以下代码了
git checkout master //合并分之后,要先切换到主分支才能拉取到新数据 git pull git checkout branchname //切换回自身分支进行开发 git merge master //合并本地分支
完成上述的代码,即可顺利的更新本地代码。如果发生冲突,就需要先手动解决了冲突才能合并本地分支。
回滚版本
- 执行以下代码即可
git reset --hard 版本号 //版本号就是那一串数字字母混合的字符串,可以用缩写,git会自动识别
结束
这周大概就只总结到这些经验,但中了这么多坑之后,总结出了git正确的使用姿势也算是一大收获了。确实很开心:)就先写到这吧,以后有更多姿势再写进来。
[笔记]如何在linux中挂起进程至后台?
前言:
最近在cent os上部署了SteamBot的程序脚本,出现需要挂起的需求,在此记录一下方法,方便以后查阅学习.
挂起进程的两种方法:
- 使用nohup
- 使用”&”符号
“&”符号:
在terminal中输入:
command &
即可将进程挂起至后台,但是退出terminal就会结束进程
nohup命令
在terminal中输入
nohup command > /dev/null 2>&1 &
即可将进程挂起至后台,并且退出terminal也不会结束进程
(这里使用 > /dev/null 是为了重定向标准输出到空,屏蔽输出)
(2>&1 的意思就是将标准错误重定向到标准输出,屏蔽错误输出)
(nohup只是防止进程在退出terminal的时候,会结束程序用的,&才是将程序放到后台的)
正确操作方法:
使用nohup command > /dev/null 2>&1 &
例如:
nohup sh ./steambot.sh > /dev/null 2>&1 &
[笔记]如何配置Apache+Laravel环境
前言:
由于开发需要,现在的后端统一使用Laravel5.5进行开发,遂整理了一些配置笔记,方便以后配置环境以及减少配置时间.
安装方法:
Laravel配置
1.切换到网站根目录
cd d:\WWW
2.使用composer安装laravel项目
[此处有个注意点,这个代码最后的foldername是指你的项目文件夹名称,如果不改的话,回车之后,composer就会在执行命令时所处的目录下新建”foldername”文件夹作为项目文件夹]
composer create-project --prefer-dist laravel/laravel=5.5.* foldername
Apache配置
1.配置Apache的Httpd.conf文件,对目标端口进行监听
2.配置Httpd.conf文件,启用httpd-vhosts.conf
3.配置httpd-vhosts.conf文件,对Laravel程序入口(public/)文件夹进行绑定.
结尾:
初次使用Laravel是会有一些迷糊,但只要用熟了,就会使用的很快的了.