git提交信息前添加分支名

为什么要在提交中添加分支名

因为git不会在提交中存储分支,只有在合并时才会在提交信息中写入分支名,如果我是林纳斯,我早把这功能加上了。

如何添加

在你的项目中,找到.git/hooks/commit-msg文件(别跟我说没有,没有你自己建一个),在commit-msg中输入

1
2
3
4
#!/bin/sh
branch=$(git symbolic-ref HEAD -q --short)
msg=$(cat $1)
echo "$branch: $msg" > $1

解释原理

git在提交前,会先调用commit-msg,就相当于触发器、拦截器、task,随便你怎么说都行,但在这里叫hooks。

提交时,会把提交信息存在一个文件中,文件名作为第一个参数传入commit-msg,你只要读这个文件,就能读到提交信息,然后把分支名加上就行了。

分享到 评论

浏览器主页竟然被劫持了

被劫持

这几天上网的时候,每次打开chrome浏览器都会打开一个奇怪的导航网站,我的主页不会被人劫持了吧,上次我的主页被劫持那还是在用IE6的时候呢。

我点开chrome设置,设置中的主页仍然是新标签页,而且以前也从未遇见过chrome的主页被修改的情况,难道说是chrome被人攻破了?能攻破chrome的人肯定能去比导航网站更好的公司吧,嗯肯定是的。

哭笑不得的结果

我打开IE,主页却没有被修改,真是见鬼了,肯定IE比chrome更容易攻破啊,结果IE却没事,那肯定是chrome的哪个文件被篡改了,而不是我整台电脑的主页都被劫持。

打开chrome的快捷方式,结果发现chrome的快捷方式中多了一个参数,而这个参数就是奇怪导航网站的网址。这下我就傻了,竟然被这么简单的修改了我的主页,赶紧把这个快捷方式中的参数去了,免得被其他人看见笑话我。

当然,也学到了小技巧,跑到别人家里的时候,把别人常用浏览器的快捷方式改了,就相当于改主页了。

分享到 评论

Photoshop CC 2014启动界面修改

起因

前几天刷微博的时候,看到平板姬的这条微博

联想到自己的PS CC的官方启动界面太过文艺,不符合本大爷的口味,所以心血来潮,想要给PS的启动界面换个血。

经过

PS CC 2014,被一些人称作PS 15,这实在是太有迷惑性了,找到一个自称适用于PS 14的启动界面修改工具,结果根本改不了PS CC 2014,在找工具的时候就走了不少弯路。

之后在google上找到了国际友人提供的工具,可以修改PS CC 2014,使用方法如下:

  1. 下载工具,并解压
  2. 打开PS的安装目录,将Resources目录拷贝至工具的pscc2014Icon目录下
  3. 运行Extract.cmd,等待提取完成
  4. 找到提取文件中High和Low目录中的SplashExtendedBackground_s0.pngSplashBackground_s0.png不会影响启动界面,所以可以不用修改。
  5. 将自己的图片放入SplashExtendedBackground_s0.png,以PS CC 2014为例,需要把自己的图片大小调整为1484*788
  6. 运行Pack.cmd,将打包好的Resources目录替换PS安装目录中的Resources目录
  7. Enjoy

结果

工具下载

自古江湖流传着“留图不留种,菊花万人捅”的规矩,为了保住菊花,自然要附上链接了。

Photoshop CC Splash Screen Extractor:
下载地址
原文链接

分享到 评论

如何判断一个页面是WebView

简单方法

通常情况下,开发者会禁止在WebView中长按,因为长按相当于浏览器中打开菜单。
长按页面中的按钮,会发生两种情况:

  • 有些应用没有禁止长按,就会出现如下状况,就知道是WebView了:

id

  • 禁用了长按的应用,在WebView中长按按钮则不会出现点击效果。

普通方法

打开设置->开发人员选项->硬件->调试GPU过度绘制,WebView中不会显示过度绘制。

分享到 评论

使用Hexo和GithubPages搭建博客

最近把之前的博客迁移到GithubPages这边,以后就不用付服务器的年租费了。本文就讲讲怎么通过Hexo和GithubPages搭建博客的

GithubPages

GithubPages类似于github中以raw的方式访问仓库中的文件,允许你通过http的方式访问该仓库中的文件。但是跟raw不同,raw不会设置content-type,所以打开html文件会显示源码,而githubPages打开html文件,会打开网页。

创建GithubPages

  1. 打开github
  2. 创建一个名为{你的用户名}.github.io的仓库
  3. 在地址栏里http://{你的用户名}.github.io/就能访问你的githubPages了

Hexo

Hexo能够把你编写的markdown(或是其他)文件,生成为html网页,虽然比起在线的编辑器要弱一点,但是由于不需要任何后端代码,是生成的静态文件,所以可以部署在各种服务器上。

Hexo主要由四部分组成:

  • Hexo库
    通过源文件和主题生成网页
  • 配置文件
    根目录下的_config.yml,配置整个站点的信息
  • 主题
    决定了整个博客的式样和交互方式
  • 源文件
    用来编写博客的markdown文件

使用Hexo编写博客

  1. 安装npm和git,Windows可以安装Node.js,安装git需要把git加入PATH
  2. 运行npm install hexo-cli -g
  3. 进入你想存放博客源文件的目录,运行hexo init <文件夹名>
    如果你已经有hexo博客源文件,那么进入博客目录,运行npm install
  4. 写一篇文章
  5. _config.yml中进行部署的设置
  6. 如果没安装hexo-deployer-git,运行npm install hexo-deployer-git --save
  7. 运行hexo deploy -g

一些命令

  • hexo deploy -ghexo generate -d都是生成后再部署
  • hexo clean可以删除public目录
    虽然我觉得还不如rm public -r
  • hexo deploy在public目录为空的时候,会进行生成
分享到 评论

设计模式(二)结构型

1、适配器模式(Adapter)

有两个类(客户类和被适配类)具有不兼容的接口,你想让他们一起工作,就需要一个适配器类来封装、转换被适配类的接口,让他能在客户类中使用。

有3类角色:

  • Client
    客户类,接口与被适配类不兼容
  • Adaptee
    被适配类,接口与客户类不兼容
  • Adapter
    适配器,被客户类使用,在适配器中转换被适配类的接口

分为两类:

  • 类适配器
    比如适配器继承Activity实现View.onClickListener,View为client,被称为类适配器。
  • 对象适配器
    比如RecyclerView.Adapter,被适配类的实例被包含在适配器中,所以被称为对象适配器。

注:对象适配器出现得更多,因为适配器可以有一个父类BaseAdapter,比起类适配器更加灵活。

2、桥接模式(Bridge)

当有一个类,他的某些属性容易变化,就用桥接模式将抽象和实现剥离,让两者可以分开变化。

有4类角色:

  • Abstraction
    包含一个Implementor的实例的抽象类,功能交由Implementor解决
  • RefinedAbstraction
    抽象的泛化、实现
  • Implementor
    一个抽象类或者接口
  • ContreteImplementor
    Implementor的泛化、实现

注:客户端里不容易出现那么善变的类,觉得用不上= =

3、组合模式(Composite)

将多个相似的对象组合,使他们能被一起操作。

例子:ViewGroup就是组合模式

有3个角色:

  • Component
    组合中,每个元素的抽象
  • Leaf
    组合中,每个元素的实现。可以有很多Leaf
  • Composite
    元素的组合,继承自Component。不同的是,新增了add和remove方法,可以增加删除元素。调用父类的方法时,会对所有元素调用一遍该方法。

注:当Component的公共方法很多时,Composite也会跟着变复杂

4、装饰模式(Decorator)

动态的给对象的方法添加功能。比起继承然后重写方法,更为灵活。

例子:Java的Writer

有4个角色:

  • Component
    被装饰的类
  • ConcreteComponent
    Component的实现或泛化
  • Decorator
    Component的装饰器,继承自Component,构造函数参数为Component
  • ConcreteDecorator
    Decorator的实现或泛化

注:与组合模式一样,当Component的公共方法很多时,Decorator工作量也会增加。用法与桥接模式类似,桥接跟适用于变化,装饰器更适用于扩展。

5、外观模式(Facade)

为大量的代码提供简单的接口。说简单点,就是子系统的外部方法。
外观模式太常用了,就比如MVC,M层和C层就都是外观模式,只要管好自己,别人干啥跟自己没关系了。

6、享元模式(Flyweight)

减少创建和修改元素的代价,重复使用元素。
通常使用哈希表以键值对的形式来存储元素,当元素再次被创建时,从哈希表中获取元素而非真的创建。

例子:RecyclerViewUniversalImageLoader

7、代理模式(Proxy)

作为另一个类的占位符,以提供访问控制、减少消耗、减少复杂性。

有3个角色:

  • Subject
    Proxy和RealSubject共同的父类
  • RealSubject
    Subject的泛化、实现
  • Proxy
    与RealSubject有同样的接口

注:很像装饰模式,但是有以下不同点:

代理模式,Proxy与RealSubject有相同的接口,和相同的构造方法。但是装饰模式的构造方法的参数一定是父类。
代理模式只能是一个类的实例的代理。但是装饰模式,只要是父类的子类,都可以被装饰。

分享到 评论

设计模式(三)行为型

1、职责链模式(Chain-of-responsibility)

当你有一个命令,以及多个处理对象,却不知道用哪个对象处理时,用职责链,一直传递直到传到那个类。
当你的if-else或switch很臃肿的时候,可以使用职责链模式。

有2个角色:

  • command objects
    一个命令
  • processing objects
    一个处理对象,包含了另一个processing object。当不满足命令的条件时,传递命令给另一个。

注:需要把switch中的default和finally也考虑进去。

2、命令模式(Command)

将行为和参数封装到一个类里。

例子:

  • 大名鼎鼎的Intent用到了一部分命令模式,其实可以再封装的
  • 网络请求,如果是短连接,则都是命令模式

有3个角色:

  • Invoker
    负责唤起Command的类,对于Intent来说,就是Context
  • Command
    一个命令,包含行为以及可选的参数
  • ConcreteCommand
    Command类的子类

3、解释器模式(Interpreter)

定义一种语言的语法,然后用解释器解释他。
解释器模式中使用了组合模式,

有3个角色:

  • Expression
    所有Expression都有方法interprete。
  • TerminalExpression
    继承Expression。负责存储Expression中的信息。也许是行为,也许是数据。
  • NonterminalExpression
    继承Expression,同时也是Expression的组合。负责解释Expression

注:你真的会有需要解释语言的时候吗。

4、迭代器模式(Iterator)

按顺序访问一个数据结构,却没有暴露数据结构。

例子:

  • Java自带的Iterator
  • SQLiter的Cursor

注:我需要讲什么吗,Java都自带了

5、中介者模式(Mediator)

降低一组类的耦合,用中介者管理他们之间的交互。

有4个角色

  • MediatorConcreteMediator
    包含多个Colleague实例
  • ColleagueConcreteColleague
    包含一个Mediator实例,用来跟其他Colleague交互

注:Mediator和Colleague之间,你中有我,我中有你,只有Colleague之间交互复杂到一定程度,才会用到吧。

6、备忘录模式(Memento)

可以记录一个对象的之前的状态,并且可以恢复。

例子:savedInstanceState

有2个角色:

  • Originator
    有内部类Memento,用来备份、恢复
  • Memento
    负责记录旧的数据

7、观察者模式(Observer)

允许Observer监听一个事件。

例子:满地都是

有2个角色:

  • Subject
    被事件触发时调用Observer
  • Observer
    在Subject中注册Observer

8、状态模式(State)

允许一个对象,当他的状态转变时,他的行为也变了。当参数不符合当前状态时,会转变状态。

有2个角色:

  • Context
    存储当前状态
  • StateContreteState
    存储状态名,以及对应的行为

9、策略模式(Strategy)

定义一系列的算法,将他们封装,使他们在运行时可以自由切换。除了不会自动变状态外,与状态模式相同。

有2个角色:

  • Context
  • StrategyContreteStrategy

注:状态模式只能自动变,策略模式只能手动变。

10、模板方法模式(Template method)

在一个抽象类中定义算法的骨架,在子类中实现他。

有2个角色:

  • AbstractClass
    包含public final的模板方法,以及一些抽象发放,模板方法不可被重写。
  • ConcreteClass
    实现父类的抽象方法

注:不像之前的那些设计模式,是让代码更灵活,模板方法模式让代码更符合约束。

11、访问者模式(Visitor)

将算法的一部分从类中剥离,而又不影响层次结构。

有2类角色:

  • Component
    有accept方法,可以接受Visitor
  • VisitorConcreteVisitor
    包含了算法,在accept中被调用。只要更换Visitor,行为就会改变。
分享到 评论

ECMAScript5特性-迭代器与生成器

今天随便翻东西,翻到了function*()。这个函数后面竟然有个星号,莫非是指针?抱着怀疑的心态,上网查到了迭代器和生成器。

迭代器(iterator)

第一次听到迭代器,还是在学习C++的时候。当时学到List这个概念,List是一个线性的存储结构,他需要一个方法,来遍历里面的内容。当时有两种方法,一个是用for循环,用索引遍历;另一个就是迭代器。
迭代器,指向List中的某一个元素,当调用迭代器的next()方法时,指向并返回下一个元素。
在ECMAScript中,迭代器的功能更为恐怖,他会遍历对象(不只是List)中的每一个元素。每一个对象的元素,都会被返回。

简单的JSON对象

1
2
var me = {name:"yk",age:21}
var it = Iterator(me)

it即为me对象的迭代器,it.next()依次返回name:”yk”、age:21,第三次则会报错。

Array

1
2
var arr = ["jiang","hu","xi"]
var it = Iterator(arr)

it.next()会返回1:”jiang”、2:”hu”、3:”xi”

function*

对,你没听错,迭代器能让函数返回多个值!这已经颠覆三观了。
当然这里的函数跟一般函数不同,我们称他为生成器(generator),生成器能返回多个值,他会生成一个迭代器,能使用到所有返回值。

1
2
3
4
5
var gen = function*(){
yield 1
yield 2
}
var it = gen()

it.next()会依次返回1、2,这里的function即表示生成器,调用function()会生成迭代器。
yield会使函数内的操作暂停,直到再次调用it.next()

分享到 评论

设计模式(一)创建型模式

设计模式可以让代码具有复用性,遇到问题,可以先考虑能不能用设计模式解决。而且经过多年来的使用和优化,设计模式显得简单可靠。
设计模式被大致分为三类,创建型、结构型和行为型。这里先讲讲创建型。

1、抽象工厂模式(Abstract Factory)

一个抽象类(或接口),可以构造一系列同一风格的类的实例。
当你需要一个新的风格的对象时,再次实现这个抽象工厂就行了。
缺点:

  • 并不是经常需要一系列的对象

2、建造者模式(Builder)

当一个类的构造过程十分复杂,或者比较容易出错时,可以考虑将类的构造从类中剥离出来。
例子:

  • Android中的AlertDialog.Builder

优点:

  • 将过程简化
  • 比构造方法更为安全
  • 可以使用链式调用

缺点:

  • 无法被继承,子类需要重新写
  • 只能构造一个特定的类

3、工厂方法模式(Factory method)

通过一个方法来构造实例,方法通过参数来判断该构造哪个类,返回哪个实例。
工厂方法分为两种,一种是内部工厂方法,一种是静态工厂方法。

例子:

  • Activity中的getSystemService()方法
  • Resouce中的getDrawable()方法
  • Fragment中的newInstance()方法,属于静态工厂方法模式

优点:

  • 扩展时,修改工厂方法就行了
  • 专注于获取实例,不需要在乎是哪个类的实例
  • 静态工厂方法比构造方法更为安全

缺点:

  • 静态工厂方法不能被继承,子类需要重新写一遍(内部方法可以继承)

    4、原型模式(Prototype)

通过克隆原型,来构造类的实例

缺点:

  • 只要实现Cloneable就等于是原型模式了,随处可见,真的还算是模式么= =

    5、单例模式(Singleton)

保证一个类只有一个实例,使用静态。常用于像工厂这样,容易被重复使用,实例间又没有太大的区别的场景。
分为两种初始化方式,一种是饿汉式初始化,类被加载时或应用启动时初始化;另一种是懒汉式初始化,类被第一次使用时初始化实例。

例子:

  • Picasso库

缺点:

  • 需要注意在编写时注意多线程下,被多次初始化的问题
分享到 评论

Atom插件(至20160220)

这年头编辑器没有几个插件,都不敢叫自己编辑器,这里就介绍一点自己常用的Atom插件。

准备工作

  • 安装Atom,官网点我
  • 安装完Atom后,同时也会安装好apm(apm不是那个每秒动几次,是Atom Package Manager),基本用法与npm一致
    安装包的方法是

    1
    apm install {你的包名}
  • (可选)设置代理,因为墙的存在,最好翻一下墙,否则可以装插件装一整天
    使用方法

    1
    apm config set proxy {协议://地址}
  • 接下来就是正片了

    效率工具

  • minimap
    在编辑器右边显示代码的概览,就像sublime的一样

  • atom-beautify
    可以格式化代码,让代码变得美观

  • markdown-scroll-sync
    在编辑markdown时,markdown的预览会滚动到你编辑的那行

美观

  • file-icons
    为文件添加图标,不同类型的文件有不同的图标
  • activate-power-mode
    安装这个包之后,在敲代码时便会有震动反馈

    语言类

  • atom-jade
    为Atom添加对Jade的支持。Jade是一款模板语言,无缝衔接javascript

  • api-workbench
    为Atom添加RAML的支持,可以编写RESTful API的文档
分享到 评论