Unix管道掃描稿php
簡單樣例:前端
$ netstat -apn | grep 8080jquery
相信這個你們常常使用,這裏就不細說了。webpack
那麼管道基本思想是什麼呢?git
do one thing and do it well
),完成一個新任務,新建一個程序,而不是在舊程序中添加新特性write programs to work together
)NodeJS中引入流概念來解決I/O異步問題,若是沒有Stream,咱們可能要這麼寫代碼:github
var http = require('http'); var fs = require('fs'); // 著名的回調地獄又來了 var server = http.createServer(function (req, res) { fs.readFile(__dirname + '/data.txt', function (err, data) { res.end(data); }); }); server.listen(8000);
但有了Stream,咱們就能夠更優雅的編寫代碼:web
var http = require('http'); var fs = require('fs'); var server = http.createServer(function (req, res) { var stream = fs.createReadStream(__dirname + '/data.txt'); // 把兩個管子接起來 stream.pipe(res); }); server.listen(8000);
想添加一個新功能?要用gzip壓縮文件?OK,能夠這麼寫:ajax
var http = require('http'); var fs = require('fs'); var oppressor = require('oppressor'); var server = http.createServer(function (req, res) { var stream = fs.createReadStream(__dirname + '/data.txt'); // 將三個管子連起來 stream.pipe(oppressor(req)).pipe(res); }); server.listen(8000);
隨着EventStream、Gulp、Webpack管道在後端的盛行,管道逐漸從後端向前端滲透,如Angular、Vuejs。咱們在Q.js、高可擴展數據層組件DB.core
中大量使用了管道過濾器(Pipe-And-Filter
)模式。後端
(webpack的核心:管道式插件)架構
那麼前端的管道又是怎樣的呢?讓咱們看看DB.core
中的例子。
DB
的設計初衷在於解決CGI拉取的通用性問題,例如:區分正確和錯誤邏輯、通用錯誤邏輯處理、登錄態通用處理。但DB
卻難以複用,由於咱們發現每一個業務的通用性各不相同,一般咱們新起一個業務老是要將DB
複製下來後作大量侵入式修改,才能適用於新的業務要求。而在齊齊互動視頻
中,咱們例如管道過濾器模式重構了咱們的DB
。 具體請參見:https://github.com/miniflycn/db
- Rule of Simplicity: Design for simplicity; add complexity only where you must.
- Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.
讓DB
幹了太多事情,致使每次幹一件事情就要插入各類代碼。經過管道過濾器模式,將每件事情拆成獨立的過濾器,每一個過濾器只作一件事,但將一件事情作到極致。
單一功能原則(Single responsibility principle)規定每一個類都應該有一個單一的功能,而且該功能應該由這個類徹底封裝起來。全部它的(這個類的)服務都應該嚴密的和該功能平行(功能平行,意味着沒有依賴)。
馬丁把功能(職責)定義爲:「改變的緣由」,而且總結出一個類或者模塊應該有且只有一個改變的緣由。一個具體的例子就是,想象有一個用於編輯和打印報表的模塊。這樣的一個模塊存在兩個改變的緣由。第一,報表的內容能夠改變(編輯)。第二,報表的格式能夠改變(打印)。這兩方面會的改變由於徹底不一樣的原由而發生:一個是本質的修改,一個是表面的修改。單一功能原則認爲這兩方面的問題事實上是兩個分離的功能,所以他們應該分離在不一樣的類或者模塊裏。把有不一樣的改變緣由的事物耦合在一塊兒的設計是糟糕的。
——from wiki
/** * _apply * @param {Array} handles 處理函數列隊,每個是一個管子 * @param {*} data 要處理的數據 * @param {Object} options 可選參數 * @param {Function} cb 處理後回調 */ _apply: function (handles, data, options, cb) { var i = 0, l = handles.length, res = data; for (i; i < l; i++) { res = handles[i].call(this, res, options); // if handle return false, just break if (res === false) return; } cb(res); },
var $ = require('jquery'); /** * DB * @class * @param {Object} options this is just a $.ajax setting * @param {Array} options.errHandles * @param {Array} options.succHandles * @param {Function} options.succ * @param {Function} options.err */ function DB(options) { this._init(options); } $.extend(DB.prototype, { _init: function (options) { this.errHandles = options.errHandles || []; this.succHandles = options.succHandles || []; this.errHandles.unshift.apply(this.errHandles, DB.options.errHandles || []); this.succHandles.unshift.apply(this.succHandles, DB.options.succHandles || []); options = $.extend({}, DB.options || {}, options); this.options = options; }, _wrap: function (options) { var self = this; options.success = function (data) { // you may want to modify this line for judging error or success data.retcode === 0 ? self._apply(self.succHandles, data, options, options.succ) : self._apply(self.errHandles, data, options, options.err); }; options.error = function (data) { self._apply(self.errHandles, data, options, options.err); }; return options; }, _apply: function (handles, data, options, cb) { var i = 0, l = handles.length, res = data; for (i; i < l; i++) { res = handles[i].call(this, res, options); // if handle return false, just break if (res === false) return; } cb(res); }, /** * ajax * @param {Object} options this is just a $.ajax setting * @param {Function} options.succ * @param {Function} options.err */ ajax: function (options) { options = this._wrap($.extend({}, this.options, options)); !options.data && (options.data = options.param); $.ajax(options); } }); $.extend(DB, { httpMethod: function (options) { var db = new DB(options); return function (opt) { db.ajax(opt); return this; }; }, extend: jQuery.extend, // default options options: {} }); module.exports = DB;
這樣咱們就能夠把之前的各類業務數據檢測,甚至是數據組裝都放在succHandles和errHandles進行。這是咱們在齊齊項目中使用的一個例子,能夠看見,咱們把數據組裝也放在了DB層進行。