jazz's blog

Good Principle of Programming

好的编程原则

*. 软件是一门工程学,其实也是一门工艺学,一个好的软件产品也是一件艺术品,构建这件艺术品有很多好的原则,下面来源于我的工作学习中总结。

*. 很多时候针对一个未知的问题,用已知的经验或知识去理解它,会存在正向或负向的偏差,甚至有时候这种偏差很大我们应该在不断的尝试中去修正偏差或发觉新的见解。

*. 我们享受对象带来的好处,但是往往我们却忽视了去维护对象的状态。一个对象的内部状态(字段)不应该超过3个

*. 一个内部状态应该只有一个引起改变它的原因。

*. 可测试性与松耦合,高内聚,无冗余和恰当的封装存在着正向的关系。

  1. 意图导向编程

    • flow
    • design
    • 接口
  2. 契约式编程

    • 契约就是“检查是否规范”;
    • 契约构成程序规格说明的一部分,只不过该说明从文档挪到了代码中;
    • 契约是一组结果为真的表达式。如若不然,契约就被违反。那按照定义,程序中就存在bug;
  3. 交互式编程

    • give me a shell
    • repl
  4. 原型开发

    • not just a demo
    • fork
    • code refactoring
    • just a bit change one by one
  5. 测试先行

    • 测试用例的分析法,使用测试来确定软件需包含的功能
    • 使用测试来完成设计

Jsonp Api Demo in Java

Java平台的JSON处理的API的演示

  1. JSON是一种轻量级数据交换格式,rails4的 respond_to do |format|拿掉xml以json取代,2013 了,再拿xml当default API就不是有一点的out了

  2. JSR-353的参考实现JSON-P将作为即将发布的JavaEE 7的一部分

  3. 以下代码演示JSONP的读写API

     import java.io.*;
    
     import javax.json.*;
     import javax.json.stream.*;
     import javax.json.stream.JsonParser.*;
    
     public class JsonDemo {
         private String address = "./json_demo.js";
    
         public static void main(String[] args) throws Exception {
             JsonDemo demo = new JsonDemo();
             demo.write();
             demo.read();
         }
    
         public void write() throws Exception{
             JsonBuilderFactory factory = Json.createBuilderFactory(null);
             JsonArray jsonArray = factory.createArrayBuilder()
                 .add(factory.createObjectBuilder()
                     .add("username", "zhijia,.zhang")
                     .add("email", "jiahut@gmail.com"))
                 .add(factory.createObjectBuilder()
                     .add("username", "lishi")
                     .add("email", "lishi@demo.com"))
                 .build();
             try (JsonWriter jsonWriter = Json.createWriter(new FileWriter(address))) {
                   jsonWriter.writeArray(jsonArray);
             }
         }
    
         public void read() throws Exception{
             JsonParserFactory factory = Json.createParserFactory(null);
             StringBuffer stb = new StringBuffer();
             String str = null;
    
             try(BufferedReader rd = new BufferedReader(new FileReader(address))){
                 while((str = rd.readLine()) != null){
                     stb.append(str);
                 }
             }
    
             JsonParser parser = factory.createParser(new StringReader(stb.toString()));
             while (parser.hasNext()) {
               Event event = parser.next();
               switch (event) {
                 case KEY_NAME: {
                   System.out.print(parser.getString() + "="); break;
                 }
                 case VALUE_STRING: {
                   System.out.println(parser.getString()); break;
                 }
               } // end switch
             }// end while
         }
     }
    
  4. 命令行下编译与运行

    • 请先下载jsonp的jar到当前目录
    • 请使用java7或以上版本

    • 编译 javac -cp .;javax.json-1.0-fab.jar JsonDemo.java

    • 运行 java -cp .;javax.json-1.0-fab.jar JsonDemo

    • 当然你也可以打开产生的json_demo.js 文件看看生成的内容

Use Git Impove Process From Coding to Testing

使用git改善代码编写与测试的过程

  1. 挂载待测试代码目录,这要得益于git原生支持共享文件系统

    • win
      • <HOST> net share project_1=e:\projects\rails /grant:administrator,full
        • 如果文件夹路径中包含空格,需用括号包含起来
        • <HOST> net share project_1 /del
      • <GUEST> net use z: \\<HOST>\project_1
        • <GUEST> net use z: /del
    • linux
      • mount
      • 使用ssh是更好的方案
  2. fork一份拷贝,checkout到bugXXX分支作修正

    • <GUEST> git clone z: project_1
    • <GUEST> git branch bugXX
    • <GUEST> git checkout bugXX
  3. push你的修正

    • 如果你直接推送到master会报错,下面方法可以解决,但是最好不要这样做 <HOST> git config --add receive.denyCurrentBranch warn

      • or <HOST> git config --add receive.denyCurrentBranch ignore
      • or <HOST> git config -e or vim .git\config append bellow config

          [receive]  
          denyCurrentBranch = warn
        
    • <GUEST> git push origin bugXX

      • 推送之前,请确保请确保HOST的工作树不处于你正推送的分支上,否则会遇见上面中提到的问题
      • 一个简化的模型是,HOST始终在master分支,GUEST始终在你修正的分支中推送补丁(ps 你不应该推送你已经合并的分支),然后HOST中去应用你的补丁
  4. 应用你的补丁
    • <HOST> git merge bugXX or git rebase bugXX

Javascript Core

javascript核心

  1. 两个作用域

    • 全局作用域
    • 闭包作用域

        for(var i = 1;i < 100;i++); i逃逸到全局作用域中  
        console.log(i); //100
      
  2. 两条原型链

    • <function>.prototype
    • <object>.constructor
  3. 两个上下文

    • 定义上下文
    • 执行上下文

        (function(){
            var callbacks = [];
            for(var i = 1;i < 100;i++){
                callbacks.push(function(){
                    console.log(i)
                });
            }
            callbacks.forEach(function(e){
                e.apply()
            });
        })()
      
  4. 两套类型系统

    • 基本类型系统空的概念用 undefined 表示
    • 对象类型系统空的概念用 null 表示

         var str = ""  
         typeof str === 'string' //true  
         str instanceof String // false 
      
  5. 两个核心概念

    • 闭包就是携带部分上下文的函数对象
      • 内部函数中的变量优先在闭包中执行变量查找,然后上一次…
    • 上下文对象就是函数执行的环境
      • 当前上下文为this
      • 浏览器全局上下文为windows
      • nodejs全局上下文为global

Ruby as Script in Action

基于ruby脚本的一些最佳实践

  1. 入口

    • 可选:拥有一个main.rb 文件,作为项目的入口文件
    • 执行起点:

        if __FILE__ == $0 # alias $PROGRAM_NAME
          # main point
        end
      
  2. 加载路径

    • 将当前路径加入ruby的load_path中,以便查找到下面的模块或模型

        $LOAD_PATH.unshift(File.join(File.dirname(__FILE__))) 
          unless $LOAD_PATH.include?(File.join(File.dirname(__FILE__)))
      
  3. 配置文件

    • 使用ymal作为配置文件,使用yaml模块来读取

        config = YAML.load_file(File.join(File.dirname(__FILE__), CONFIG_FILE))
      
  4. 命令行参数

    • 使用optparse模块处理命令行参数

         OptionParser.new do |opts|
              # options[:action] = args
              opts.on("--open [project_name]","open a sublime projec") do |project_info|
                options[:open] = project_info
              end
      
              opts.on_tail("-h", "--help", "Show this message") do
                puts opts
                exit
              end
          end.parse!
      
      
          options.each do |action , argv|
            SublProject.send action.to_sym,*argv
          end
      
  5. 模块

    • 一个模块只应该解决一个核心问题。比如解析特定格式的文件,返回解析后的模型数据
      • 可选: 以功能命名相应的文件夹,如parser
    • 模块的接口设计为返回一个模型的实例
  6. 模型

    • 项目需求分析阶段,抽象出的核心概念都应该作为一个模型
    • 模型应该采用rails的充血模型设计,模型之间能导航,但不需持久化
    • 当代码在响应需求变化时显得复杂,这时候应该抽象出一个模型,在业务中插入一个对象来应对业务的变化。
    • 可选:把所有模型保存到domain或models文件夹中

Python Module vs. Package

模块 vs. 包

  1. 一个.py文件就是一个模块,但是一个模块未必就对应一个.py文件
    1. in lib/os.py it injects “sys.modules[‘os.path’] = path” so that you’re able to do “import os.path” as though it was a submodule.
    2. sys.modules is a dict in which modules are cached. When you import a module, if it already has been imported somewhere, it gets the instance stored in sys.modules.
  2. 包就是一个文件夹下放一个 “_init_.py”
    1. The _init.py files are required to make Python treat the directories as containing packages.
    2. _init_.py can just be an empty file, but it can also execute initialization code for the package or set the _all_ variable
    3. 多级package _init_.py从顶至底依次被执行
  3. import用于导入包或模块
    1. A module’s body executes immediately the first time the module is imported in a given run of a program
    2. An import statement creates a new namespace containing all the attributes of the module

获取帮助

  1. dir(object) => 列出object的方法
  2. help(object) => 列出object的文档
    *object 可以是模块,类 或者 函数对象

MarkDown Syntax

记录一下Markdown的语法要点


  • MD的语法全部由标点符号所组成,一般语法格式为标点符号后加一个空格

  • 与HTML之间

    • 不在Markdown涵盖范围之外的标签,都可以直接在文件里面用HTML撰写
    • 只有区块元素──比如<div><table><pre><p>标签,必需在前后加上空白
    • HTML的区段标签<span><cite><del>则不受限制
    • Markdown语法在HTML区块标签中将不会被进行处理
  • 不要用tab,或者把tab设置为4个空格

  • 行尾两个空格产生换行

  • 缩进产生代码块,并结束于空行

  • 如用到语法中的标点符号的时前面加反斜杠转义“/”

Octopress Key Point

使用octopress的一下关键性要点

  • 执行bundle绑定rake版本

    • bundle exec rake new_post[‘title’]
      • title里大可以包含空格
  • 本地review

    • bundle exec rake preview
  • 生成

    • bundle exec rake generate
  • 提交

    • 管理员模式的命令行和cygwin下的git
    • bundle exec rake deploy
  • 创建文章别忘记备份源文件

    • git add source/_post/new_post

    • git commit -m “update source : new_post”

  • win下deploy的一些关键性细节

    • set LC_ALL=zh_CN.UTF-8

      • 多少次跌在这个坑里,win的默认使用gbk编码,同时console默认显示的也是gbk编码
    • 生成的markdown文件请务必保证是utf-8无bom编码

      • 又是一个坑.
  • 更新系统享受新特性

    • git pull octopress master