├── app ├── booktree.png ├── templates │ └── description.html ├── scripts │ ├── Utils.js │ ├── main.js │ └── render.js ├── styles │ ├── layout.css │ ├── mifa.min.css │ └── tooltipster.css ├── data │ ├── lang.json │ ├── cd.json │ ├── code.json │ ├── arch.json │ ├── ml.json │ └── frontend.json ├── lib │ ├── FileSaver.min.js │ ├── json.js │ ├── text.js │ ├── lettuce.js │ ├── underscore-min.js │ ├── jquery.tooltipster.min.js │ └── underscore-min.map └── assets │ ├── lang.svg │ ├── cd.svg │ ├── code.svg │ ├── frontend.svg │ └── ml.svg ├── screenshots ├── cd.jpg ├── cd.png ├── dsl.jpg ├── dsl.png ├── ml.jpg ├── ml.png ├── arch.jpg ├── arch.png ├── code.jpg ├── code.png ├── frontend.jpg └── frontend.png ├── .gitignore ├── .travis.yml ├── bower.json ├── .jshintrc ├── .editorconfig ├── package.json ├── gulpfile.js ├── index.html ├── README.md └── LICENSE /app/booktree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/app/booktree.png -------------------------------------------------------------------------------- /screenshots/cd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/cd.jpg -------------------------------------------------------------------------------- /screenshots/cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/cd.png -------------------------------------------------------------------------------- /screenshots/dsl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/dsl.jpg -------------------------------------------------------------------------------- /screenshots/dsl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/dsl.png -------------------------------------------------------------------------------- /screenshots/ml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/ml.jpg -------------------------------------------------------------------------------- /screenshots/ml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/ml.png -------------------------------------------------------------------------------- /screenshots/arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/arch.jpg -------------------------------------------------------------------------------- /screenshots/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/arch.png -------------------------------------------------------------------------------- /screenshots/code.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/code.jpg -------------------------------------------------------------------------------- /screenshots/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/code.png -------------------------------------------------------------------------------- /screenshots/frontend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/frontend.jpg -------------------------------------------------------------------------------- /screenshots/frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phodal/booktree/gh-pages/screenshots/frontend.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | .sass-cache 5 | bower_components 6 | test/bower_components 7 | .idea 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | notifications: 6 | email: false 7 | 8 | branches: 9 | only: 10 | - gh-pages 11 | -------------------------------------------------------------------------------- /app/templates/description.html: -------------------------------------------------------------------------------- 1 |
6 | 7 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skillock", 3 | "private": true, 4 | "dependencies": { 5 | "jquery": "2.1.3", 6 | "d3": "3.5.5", 7 | "requirejs": "2.1.16", 8 | "knockout": "2.3.0", 9 | "dagre-d3": "~0.4.17", 10 | "lettuce": "~0.2.3" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/scripts/Utils.js: -------------------------------------------------------------------------------- 1 | define(['lib/knockout'], function(ko) { 2 | 'use strict'; 3 | function getSkillById(books, id) { 4 | var result = []; 5 | ko.utils.arrayForEach(books, function (skill) { 6 | if(skill.id === id){ 7 | result = skill; 8 | } 9 | }); 10 | return result; 11 | } 12 | 13 | return { 14 | getSkillById: getSkillById 15 | }; 16 | }); 17 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "browser": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "immed": true, 8 | "indent": 2, 9 | "latedef": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "quotmark": "single", 13 | "undef": true, 14 | "unused": false, 15 | "strict": true, 16 | "jquery": true, 17 | "laxcomma": true, 18 | "scripturl": true, 19 | "predef": [ 20 | "require", 21 | "define", 22 | "escape", 23 | "console" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # we recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | 23 | [{package,bower}.json] 24 | indent_style = space 25 | indent_size = 2 26 | -------------------------------------------------------------------------------- /app/scripts/main.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl: 'app', 3 | paths: { 4 | jquery: 'lib/jquery-2.1.3', 5 | json: 'lib/json', 6 | d3: 'lib/d3.min', 7 | 'dagre-d3': 'lib/dagre-d3.min', 8 | text: 'lib/text', 9 | lettuce: 'lib/lettuce', 10 | 'underscore': 'lib/underscore-min', 11 | 'jquery.tooltipster': 'lib/jquery.tooltipster.min' 12 | }, 13 | 'shim': { 14 | 'jquery.tooltipster': { 15 | deps: ['jquery'] 16 | }, 17 | 'dagre-d3': { 18 | deps: ['d3'] 19 | } 20 | } 21 | }); 22 | 23 | require(['lib/knockout', 'scripts/render', 24 | 'json!data/code.json', 25 | 'json!data/frontend.json', 26 | 'json!data/cd.json', 27 | 'json!data/lang.json', 28 | 'json!data/arch.json', 29 | 'json!data/ml.json' 30 | ], 31 | function (ko, render, 32 | code, 33 | frontend, 34 | cd, 35 | lang, 36 | arch, 37 | ml) { 38 | 'use strict'; 39 | 40 | render.renderPage(code, '#code'); 41 | render.renderPage(frontend, '#frontend'); 42 | render.renderPage(cd, '#cd'); 43 | render.renderPage(lang, '#lang'); 44 | render.renderPage(arch, '#arch'); 45 | render.renderPage(ml, '#ml'); 46 | }); 47 | -------------------------------------------------------------------------------- /app/styles/layout.css: -------------------------------------------------------------------------------- 1 | section { 2 | margin-bottom: 3em; 3 | } 4 | 5 | #tree { 6 | width: 1200px; 7 | margin: 0 auto; 8 | } 9 | 10 | svg { 11 | width: 1440px; 12 | overflow: hidden; 13 | margin: auto 0; 14 | } 15 | 16 | .node rect { 17 | stroke: #333; 18 | fill: #fff; 19 | } 20 | 21 | g.node rect { 22 | stroke: #bdc3c7; 23 | stroke-width: 2.5px; 24 | cursor: pointer; 25 | } 26 | 27 | g.node rect.inner { 28 | fill: white; 29 | } 30 | 31 | g.node rect.outer { 32 | position: absolute; 33 | display: none; 34 | stroke-dasharray: 4px; 35 | stroke-opacity: 0.5; 36 | fill: transparent; 37 | } 38 | 39 | g.selected rect.outer { 40 | display: inline; 41 | } 42 | 43 | rect.selection { 44 | stroke: gray; 45 | stroke-dasharray: 4px; 46 | stroke-opacity: 0.5; 47 | fill: transparent; 48 | } 49 | 50 | .edgePath path { 51 | stroke: gray; 52 | fill: gray; 53 | stroke-width: 1.5px; 54 | } 55 | 56 | .node text { 57 | pointer-events: none; 58 | fill: #34495e; 59 | } 60 | 61 | /* disable text selection */ 62 | svg *::selection { 63 | background: transparent; 64 | } 65 | 66 | svg *::-moz-selection { 67 | background: transparent; 68 | } 69 | 70 | svg *::-webkit-selection { 71 | background: transparent; 72 | } 73 | 74 | path { 75 | color: #ddd; 76 | fill: #ddd; 77 | } 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "engines": { 4 | "node": ">=0.10.0" 5 | }, 6 | "scripts": { 7 | "test": "mocha --reporter spec" 8 | }, 9 | "devDependencies": { 10 | "chai": "~1.8.0", 11 | "connect": "^3.0.1", 12 | "connect-livereload": "^0.5.0", 13 | "del": "^0.1.0", 14 | "expect.js": ">= 0.3.1", 15 | "gulp": "^3.6.0", 16 | "gulp-autoprefixer": "^1.0.1", 17 | "gulp-cache": "^0.2.2", 18 | "gulp-csso": "^0.2.6", 19 | "gulp-filter": "^1.0.2", 20 | "gulp-flatten": "^0.0.4", 21 | "gulp-if": "^1.2.1", 22 | "gulp-jshint": "^1.5.3", 23 | "gulp-livereload": "^2.0.0", 24 | "gulp-load-plugins": "^0.7.1", 25 | "gulp-mocha": "2.0.0", 26 | "gulp-plumber": "^0.6.3", 27 | "gulp-replace": "^0.4.0", 28 | "gulp-size": "^1.1.0", 29 | "gulp-uglify": "^1.0.1", 30 | "gulp-useref": "^1.0.2", 31 | "istanbul": "^0.3.0", 32 | "jsdom": "3.1.2", 33 | "jshint-stylish": "^1.0.0", 34 | "json-concat": "0.0.0-alpha.1.0", 35 | "lazypipe": "^0.2.1", 36 | "main-bower-files": "^2.1.0", 37 | "mocha": "2.1.0", 38 | "mocha-jsdom": "^0.2.1", 39 | "mocha-lcov-reporter": "^0.0.1", 40 | "opn": "^1.0.0", 41 | "requirejs": "2.1.16", 42 | "serve-index": "^1.1.4", 43 | "serve-static": "^1.4.0", 44 | "should": ">= 3.2.0", 45 | "wiredep": "^2.0.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/data/lang.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "id": 1, 5 | "description": "龙书!龙书!龙书!", 6 | "title": "《编译原理》", 7 | "douban": "http://book.douban.com/subject/3296317/" 8 | }, 9 | { 10 | "id": 3, 11 | "description": "旨在传授开发语言应用(工具)的经验和理念,帮助读者构建自己的语言应用。", 12 | "title": "《编程语言实现模式》", 13 | "depends": [ 14 | 1 15 | ], 16 | "douban": "http://book.douban.com/subject/10482195/" 17 | }, 18 | { 19 | "id": 2, 20 | "description": "书中以问答方式告诉为什么要创建某种编程语言、它在技术上如何开发、如何教授和学习,以及它如何顺应时代发展等。你会发现构建成功编程语言所需的思想和步骤,它广受欢迎的原因,以及如何处理程序员常见的问题。", 21 | "title": "《编程之魂》", 22 | "douban": "http://book.douban.com/subject/4719230/" 23 | }, 24 | { 25 | "id": 4, 26 | "description": "本书堪称动态语言设计模式。", 27 | "title": "《Ruby元编程》", 28 | "douban": "http://book.douban.com/subject/7056800/" 29 | }, 30 | { 31 | "id": 5, 32 | "description": "不仅介绍如何使用DSL解决问题,还会使用Ruby、Groovy、Scala、Clojure等现代语言阐述DSL的设计与实现,针对这些语言所代表的不同编程范式深入讨论其在DSL设计上的优劣。", 33 | "title": "《领域专用语言实战》", 34 | "depends": [ 35 | 3, 4, 2 36 | ], 37 | "douban": "http://book.douban.com/subject/25741352/" 38 | }, 39 | { 40 | "id": 6, 41 | "description": "全面详尽地讲解了各种DSL及其构造方式,揭示了与编程语言无关的通用原则和模式,阐释了如何通过DSL有效提高开发人员的生产力以及增进与领域专家的有效沟通,能为开发人员选择和使用DSL提供有效的决策依据和指导方法。", 42 | "title": "《领域特定语言》", 43 | "depends": [ 44 | 5 45 | ], 46 | "douban": "http://book.douban.com/subject/21964984/" 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* jshint node:true */ 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var $ = require('gulp-load-plugins')(); 5 | var mocha = require('gulp-mocha'); 6 | 7 | gulp.task('contact', function () { 8 | var jsonConcat = require("json-concat"); 9 | 10 | jsonConcat({ 11 | src: ["data/0.json", "data/1-html.json"], 12 | dest: "./data/data.json" 13 | }, function (json) { 14 | console.log(json); 15 | }); 16 | }); 17 | 18 | gulp.task('jshint', function () { 19 | return gulp.src('app/scripts/**/*.js') 20 | .pipe($.jshint()) 21 | .pipe($.jshint.reporter('jshint-stylish')) 22 | .pipe($.jshint.reporter('fail')); 23 | }); 24 | 25 | gulp.task('connect', function () { 26 | var serveStatic = require('serve-static'); 27 | var serveIndex = require('serve-index'); 28 | var app = require('connect')() 29 | .use(require('connect-livereload')({port: 35729})) 30 | .use(serveStatic('./')) 31 | .use(serveIndex('./')); 32 | 33 | require('http').createServer(app) 34 | .listen(9000) 35 | .on('listening', function () { 36 | console.log('Started connect web server on http://localhost:9000'); 37 | }); 38 | }); 39 | 40 | gulp.task('serve', ['connect', 'watch'], function () { 41 | require('opn')('http://localhost:9000'); 42 | }); 43 | 44 | gulp.task('watch', ['connect'], function () { 45 | $.livereload.listen(); 46 | 47 | gulp.watch([ 48 | 'index.html', 49 | 'app/scripts/**.js', 50 | 'app/images/**/*', 51 | 'app/styles/**/*.css', 52 | 'app/templates/**.html', 53 | 'app/logo/**/*', 54 | 'data/**.json' 55 | ]).on('change', $.livereload.changed); 56 | }); 57 | 58 | gulp.task('build', ['jshint'], function () { 59 | return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true})); 60 | }); 61 | 62 | gulp.task('default', function () { 63 | gulp.start('build'); 64 | }); 65 | -------------------------------------------------------------------------------- /app/data/cd.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "id": 1, 5 | "description": "讲述了在预算和时间要求下软件开发人员和项目经理如何使用敏捷开发完成项目:使用真实案例讲解如何用极限编程来设计、测试、重构和结对编程;包含了极具价值的可重用的C++和Java源代码;还重点讲述了如何使用UML和设计模式解决面向客户系统的问题。", 6 | "title": "《敏捷软件开发:原则、模式与实践》", 7 | "depends": [ 8 | 2 9 | ], 10 | "douban": "http://book.douban.com/subject/1140457/" 11 | }, 12 | { 13 | "id": 2, 14 | "description": "这本书讲解了代码管理工具和系统的历史和发展,然后从小型团队、中大型团队、分布式大团队、基于微服务的团队及开源团队的角度总结了代码管理的核心技术及实践经验,其中包括不同类型的团队对代码管理工具和系统的选择,以及代码管理的流程、策略和技巧,还有一些代码管理工具和系统的难点、痛点等", 15 | "title": "《代码管理核心技术及实践》", 16 | "douban": "https://book.douban.com/subject/27611269/" 17 | }, 18 | { 19 | "id": 3, 20 | "description": "以一次自评价测试开篇,从软件测试的心理学和经济学入手,探讨了代码检查、走查与评审、测试用例的设计、模块(单元)测试、系统测试、调试等主题,以及极限测试、互联网应用测试等高级主题,全面展现了作者的软件测试思想。", 21 | "title": "《软件测试的艺术》", 22 | "douban": "http://book.douban.com/subject/10549782/" 23 | }, 24 | { 25 | "id": 5, 26 | "description": "自动化测试", 27 | "title": "《Cucumber:行为驱动开发指南》", 28 | "douban": "http://book.douban.com/subject/24843412/" 29 | }, 30 | { 31 | "id": 6, 32 | "description": "测试是敏捷开发的关键组成部分。敏捷方法的广泛应用使人们开始关注如何有效测试,同时敏捷项目改变了测试人员的角色。", 33 | "title": "《敏捷软件测试》", 34 | "depends": [ 35 | 3, 5 36 | ], 37 | "douban": "http://book.douban.com/subject/5338399/" 38 | }, 39 | { 40 | "id": 7, 41 | "description": "构造系统在软件开发过程中处于核心地位,它的正确性和性能,在一定程度上决定了软件开发成果的质量和软件开发过程的效率。", 42 | "title": "《深入理解软件构造系统》", 43 | "douban": "http://book.douban.com/subject/10769838/" 44 | }, 45 | { 46 | "id": 8, 47 | "description": "旨在指导配置管理从业者如何处理日常工作中需要面对的各种复杂情况。", 48 | "title": "《配置管理最佳实践》", 49 | "douban": "http://book.douban.com/subject/25717078/" 50 | }, 51 | { 52 | "id": 10, 53 | "description": "讲述如何实现更快、更可靠、低成本的自动化软件交付,描述了如何通过增加反馈,并改进开发人员、测试人员、运维人员和项目经理之间的协作来达到这个目标。", 54 | "title": "《持续交付:发布可靠软件的系统方法》", 55 | "depends": [ 56 | 1, 6, 7, 8 57 | ], 58 | "douban": "http://book.douban.com/subject/6862062/" 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /app/lib/FileSaver.min.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 2 | var saveAs=saveAs||function(e){"use strict";if(!("undefined"==typeof e||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,d=/CriOS\/[\d]+/.test(navigator.userAgent),f=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",u=4e4,c=function(e){var t=function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()};setTimeout(t,u)},l=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(a){f(a)}}},v=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob([String.fromCharCode(65279),e],{type:e.type}):e},p=function(t,f,u){u||(t=v(t));var p,w=this,m=t.type,y=m===s,S=function(){l(w,"writestart progress write writeend".split(" "))},h=function(){if((d||y&&i)&&e.FileReader){var o=new FileReader;return o.onloadend=function(){var t=d?o.result:o.result.replace(/^data:[^;]*;/,"data:attachment/file;"),n=e.open(t,"_blank");n||(e.location.href=t),t=void 0,w.readyState=w.DONE,S()},o.readAsDataURL(t),void(w.readyState=w.INIT)}if(p||(p=n().createObjectURL(t)),y)e.location.href=p;else{var r=e.open(p,"_blank");r||(e.location.href=p)}w.readyState=w.DONE,S(),c(p)};return w.readyState=w.INIT,r?(p=n().createObjectURL(t),void setTimeout(function(){o.href=p,o.download=f,a(o),S(),c(p),w.readyState=w.DONE})):void h()},w=p.prototype,m=function(e,t,n){return new p(e,t||e.name||"download",n)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,n){return t=t||e.name||"download",n||(e=v(e)),navigator.msSaveOrOpenBlob(e,t)}:(w.abort=function(){},w.readyState=w.INIT=0,w.WRITING=1,w.DONE=2,w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null,m)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define("FileSaver.js",function(){return saveAs}); -------------------------------------------------------------------------------- /app/data/code.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "id": 1, 5 | "description": "尽管在国内,我们很少听到开发人员写测试,就更少听人们谈论TDD。虽然我不是TDD的死忠,但是我觉得TDD还是很有好处的。特别是当你的函数特别长的时候,它可以驱使你写出更短的函数——更多的函数。红->绿->重构,就是这么简单。", 6 | "title": "《测试驱动开发》", 7 | "douban": "http://book.douban.com/subject/25735501/" 8 | }, 9 | { 10 | "id": 2, 11 | "description": "红->绿->重构。如果重构之前没有测试,我相信你可能是想换个工作了。好的代码是重构出来的,而不是一开始就写出来的——除非你的代码不用于任何业务。反正,就是程序员必读,不想多说。", 12 | "title": "《重构: 改善既有代码的设计》", 13 | "depends": [ 14 | 1 15 | ], 16 | "douban": "http://book.douban.com/subject/26575459/" 17 | }, 18 | { 19 | "id": 3, 20 | "description": "GoF的《设计模式》一书很薄,所以也很抽象。第一次看《设计模式》的时候,硬着头皮看了几天,然后放弃了。。。不过,Head First系列可以将各种枯燥的设计生起起来,这是一本非常适合入门设计模式的书籍没有之一。", 21 | "title": "《Head First设计模式》", 22 | "douban": "http://book.douban.com/subject/2243615/" 23 | }, 24 | { 25 | "id": 4, 26 | "description": "比Head First更深入,但是比DP简单。作者选用了一些常用或者说用到的模式,讲述了为什么在这里适合用它。", 27 | "title": "《设计模式解析》", 28 | "depends": [ 29 | 3 30 | ], 31 | "douban": "http://book.douban.com/subject/1850191/" 32 | }, 33 | { 34 | "id": 5, 35 | "description": "纳尼!你居然不想买这本书?", 36 | "title": "《易读代码的艺术/编写可读代码的艺术》", 37 | "douban": "http://book.douban.com/subject/10773334/" 38 | }, 39 | { 40 | "id": 6, 41 | "description": "书中给了很方法与规范,遵循它们可以写出整洁的代码。但是整洁并不意味着你应该让代码简单!", 42 | "title": "《代码整洁之道》", 43 | "depends": [ 44 | 5 45 | ], 46 | "douban": "http://book.douban.com/subject/4199741/" 47 | }, 48 | { 49 | "id": 7, 50 | "description": "这本书的中文名字应该叫《重构到模式》!!!重构代码到设计模式就这么简单。", 51 | "title": "《重构与模式》", 52 | "depends": [ 53 | 2, 6 54 | ], 55 | "douban": "http://book.douban.com/subject/1917706/" 56 | }, 57 | { 58 | "id": 8, 59 | "description": "必读,并且值得多读几遍。", 60 | "title": "《设计模式》", 61 | "depends": [ 62 | 4, 7, 9 63 | ], 64 | "douban": "http://book.douban.com/subject/1052241/" 65 | }, 66 | { 67 | "id": 9, 68 | "description": "首先书名很扯!!!这本书更适合叫《设计模式要素》!这本书提取了设计模式中的一些基本元素,很具有启发性。", 69 | "title": "《元素模式》", 70 | "depends": [ 71 | 8 72 | ], 73 | "douban": "http://book.douban.com/subject/25908396/" 74 | } 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /app/data/arch.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "id": 1, 5 | "description": "经典!", 6 | "title": "《企业应用架构模式》" 7 | }, 8 | { 9 | "id": 2, 10 | "description": "本书将成为与《设计模式》一样的被读者广泛认可的经典之作。《设计模式》只探讨了面向对象开发的一个抽象层级,而本书涵盖了三个:高层的架构模式、中层的设计模式,以及特定语言的成例。", 11 | "title": "《面向模式的软件架构卷1: 模式系统》", 12 | "depends": [ 13 | 1, 10 14 | ], 15 | "douban": "http://book.douban.com/subject/25741382/" 16 | }, 17 | { 18 | "id": 3, 19 | "description": "全面详尽地讲解了各种DSL及其构造方式,揭示了与编程语言无关的通用原则和模式,阐释了如何通过DSL有效提高开发人员的生产力以及增进与领域专家的有效沟通,能为开发人员选择和使用DSL提供有效的决策依据和指导方法。", 20 | "title": "《领域特定语言》", 21 | "douban": "http://book.douban.com/subject/21964984/" 22 | }, 23 | { 24 | "id": 4, 25 | "description": "分别从战略和战术层面详尽地讨论了如何实现DDD,其中包含了大量的最佳实践、设计准则和对一些问题的折中性讨论。", 26 | "title": "《实现领域驱动设计》", 27 | "depends": [ 28 | 3 29 | ], 30 | "douban": "http://book.douban.com/subject/25844633/" 31 | }, 32 | { 33 | "id": 5, 34 | "description": "全书围绕着设计和开发实践,结合若干真实的项目案例,向读者阐述如何在真实的软件开发中应用领域驱动设计。 ", 35 | "title": "《领域驱动设计》", 36 | "depends": [ 37 | 4 38 | ], 39 | "douban": "http://book.douban.com/subject/5344973/" 40 | }, 41 | { 42 | "id": 6, 43 | "description": "主要面向软件开发者群体,尤其是对敏捷开发感兴趣的程序设计人员。浮现式设计是一种敏捷技术,强调在开发过程中不断演进。", 44 | "title": "《浮现式设计:专业软件开发的演进本质》", 45 | "douban": "http://book.douban.com/subject/6757781/" 46 | }, 47 | { 48 | "id": 7, 49 | "description": "作者建议根据项目面临的风险来调整架构设计的成本,并从多个视角阐述了软件架构的建模过程和方法,包括用例模型、概念模型、域模型、设计模型和代码模型等。", 50 | "title": "《恰如其分的软件架构》", 51 | "douban": "http://book.douban.com/subject/24872314/" 52 | }, 53 | { 54 | "id": 10, 55 | "description": "书中揭示了模块化的重要性,如何实现模块化,以及如何使用OSGi实现模块化架构。", 56 | "title": "《Java应用架构设计》", 57 | "douban": "http://book.douban.com/subject/25770095/" 58 | }, 59 | { 60 | "id": 8, 61 | "description": "从全新的视角重新解读软件架构,揭示软件架构的本质,是一本强调实践、注重实效、轻量级、面向开发人员的软件架构指南。", 62 | "title": "《程序员必读之软件架构》", 63 | "depends": [ 64 | 6, 7 65 | ], 66 | "douban": "http://book.douban.com/subject/26248182/" 67 | }, 68 | { 69 | "id": 9, 70 | "description": "围绕5个主题领域来组织《架构之美》的内容:概述、企业应用、系统、最终用户应用和编程语言。", 71 | "title": "《架构之美》", 72 | "depends": [ 73 | 2, 5, 8 74 | ], 75 | "douban": "http://book.douban.com/subject/4086029/" 76 | } 77 | ] 78 | } 79 | -------------------------------------------------------------------------------- /app/lib/json.js: -------------------------------------------------------------------------------- 1 | /** @license 2 | * RequireJS plugin for loading JSON files 3 | * - depends on Text plugin and it was HEAVILY "inspired" by it as well. 4 | * Author: Miller Medeiros 5 | * Version: 0.4.0 (2014/04/10) 6 | * Released under the MIT license 7 | */ 8 | define(['text'], function(text){ 9 | 10 | var CACHE_BUST_QUERY_PARAM = 'bust', 11 | CACHE_BUST_FLAG = '!bust', 12 | jsonParse = (typeof JSON !== 'undefined' && typeof JSON.parse === 'function')? JSON.parse : function(val){ 13 | return eval('('+ val +')'); //quick and dirty 14 | }, 15 | buildMap = {}; 16 | 17 | function cacheBust(url){ 18 | url = url.replace(CACHE_BUST_FLAG, ''); 19 | url += (url.indexOf('?') < 0)? '?' : '&'; 20 | return url + CACHE_BUST_QUERY_PARAM +'='+ Math.round(2147483647 * Math.random()); 21 | } 22 | 23 | //API 24 | return { 25 | 26 | load : function(name, req, onLoad, config) { 27 | if (( config.isBuild && (config.inlineJSON === false || name.indexOf(CACHE_BUST_QUERY_PARAM +'=') !== -1)) || (req.toUrl(name).indexOf('empty:') === 0)) { 28 | //avoid inlining cache busted JSON or if inlineJSON:false 29 | //and don't inline files marked as empty! 30 | onLoad(null); 31 | } else { 32 | text.get(req.toUrl(name), function(data){ 33 | var parsed; 34 | if (config.isBuild) { 35 | buildMap[name] = data; 36 | onLoad(data); 37 | } else { 38 | try { 39 | parsed = jsonParse(data); 40 | } catch (e) { 41 | onLoad.error(e); 42 | } 43 | onLoad(parsed); 44 | } 45 | }, 46 | onLoad.error, { 47 | accept: 'application/json' 48 | } 49 | ); 50 | } 51 | }, 52 | 53 | normalize : function (name, normalize) { 54 | // used normalize to avoid caching references to a "cache busted" request 55 | if (name.indexOf(CACHE_BUST_FLAG) !== -1) { 56 | name = cacheBust(name); 57 | } 58 | // resolve any relative paths 59 | return normalize(name); 60 | }, 61 | 62 | //write method based on RequireJS official text plugin by James Burke 63 | //https://github.com/jrburke/requirejs/blob/master/text.js 64 | write : function(pluginName, moduleName, write){ 65 | if(moduleName in buildMap){ 66 | var content = buildMap[moduleName]; 67 | write('define("'+ pluginName +'!'+ moduleName +'", function(){ return '+ content +';});\n'); 68 | } 69 | } 70 | 71 | }; 72 | }); 73 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |一直画/写一个推荐书单来供大家参考,无奈找不到一本合适的形式。有一天,想到了之前的技术树 https://github.com/phodal/sherlock,便开始落地了。
19 |我深知自己的知识有限,所以写下本文以便和大家切磋交流。欢迎通过 GitHub 的Issues或者直接Pull Requests方式来分享你的经验。期待你的反馈。
20 | 21 |
23 | 说明: 完成工作是一件很容易的事,如何更好地完成工作就需要更多地学习。并且我坚信每一个有技术热情的人,都希望可以看到自己写的框架可以无处不在。 24 | 25 |
这是一本关于『技术是什么,它是如何进化』的书。新的技术是根据于我们当前的目的、一个可实现的原理、一种新现象而发明的。并且,新的技术都是基于之前的技术发展出来的。
28 |So,通过研究现有技术的一些发展,我们可以预料到一些新的技术的出现。尽管新的技术并没有解决一些根本性问题,如业务,但是它是为了业务而简化现有的技术。
29 |本图已被《JavaScript 框架设计:第 2 版》收录。
36 | 37 | 38 |相关文章:
50 |相关文章:
58 |64 | 详细讨论了类和函数命名、变量命名、数据类型和控制结构、代码布局等编程的最基本要素,也讨论了防御式编程、表驱动法、协同构建、开发者测试、性能优化等有效开发实践,这些都服务于软件的首要技术使命:管理复杂度。 65 |
66 |© 2015 Phodal Huang. See LICENSE.txt in this directory.