Javascript实体对象生成器

 弄了一上午 模拟以前C#写了一个Javascript的对象生成器,支持对象转JSON集合,还有单属性访问器。没事技术含量为了熟悉原型以及原型链做的练习。

//申明扩展类
var ExtendClass = function () { };

//属性访问器
ExtendClass.prototype.accessor = function () {
    this.get = function () {
        return this.val;
    }
    this.set = function (val) {
        if (arguments.length == 2) {
            if (arguments[1] instanceof Function) {
                arguments[1](val);
            }
            val = arguments[0];
        }
        this.val = val;
    }
}
//值正确性校验
ExtendClass.prototype.isCorrectValue = function (val) {
    var flag = true;
    if (val instanceof Object && val instanceof Function && val == undefined && isNaN(isFinite)) {
        flag = false;
    }
    return flag;
}
//动态实体生成
ExtendClass.prototype.entityAccessor = function (entityList) {
    var entity = entityList;
    if (entity instanceof Object) {
        for (var i in entity) {
            var access = new extend.accessor();
            this.constructor.prototype[i] = access;
            var et = entity[i];
            var val = et["value"];
            if (extend.isCorrectValue(val)) {
                //判断是否存在附加函数
                if (et["setVerify"]) {
                    this.constructor.prototype[i].set.call(this.constructor.prototype[i], val, et["setVerify"])
                } else {
                    this.constructor.prototype[i].set(val);
                }
            }
        }
    }
}
//实体转换JSON输出
ExtendClass.prototype.getEntityList = function (entityObj) {
    var entList = entityObj;
    var tempArray = [];
    if (entList instanceof this.entityAccessor) {
        for (var en in entList) {
            tempArray.push(JSON.parse('[{ "' + en + '": "' + entList[en].get() + '" }]')[0]);
        }
    }
    return tempArray;
}


var setVer = function (val) {
    if (parseInt(val) < 0) {
        throw Error(this.lineNumber + "not age number!");
    }
}
var entityList = {
    "name": { value: "topaz.tang" },
    "age": { value: 25, get: true, setVerify: setVer },
    "sex": { value: "Men", get: true },
    "birthday": { value: "1988-11-10" }
}


var extend = new ExtendClass();

var entityFn = new extend.entityAccessor(entityList);   //实例化实体生成器  参数1:实体JSON列表
console.log(entityFn.age.get()) //输出  set函数设置的值.
var allEntity = extend.getEntityList(entityFn);   //输出 [{key:value},{key:value},{key:value}...n]
console.log(JSON.stringify(allEntity));

祝大家快乐工作,快乐生活。

谢谢!

SVN管理Github代码配置

研究了一下Github,使用它原本的管理工具虽然界面简洁明了但是还是不太习惯这种操作方式,而且公司也不能直接上外网,需要代理来访问internet网,无奈看了半天帮助原来Github是可以用SVN来管理的,小激动了一下,设置好了SVN的代理准备开始尝试配置Github代码导入到SVN。话不多说 具体的配置方法见以下步骤。

· 建立新的Repository

clip_image0021[1]

·填写Repository基本信息

clip_image004

·初始化Repository并创建Readme说明文件

clip_image006

·填写Readme说明文件内容

clip_image008 继续阅读SVN管理Github代码配置

中介者模式(Mediator)

2205545c1-2 function extend(subclass, superclass) { var F = function () { }; F.prototype = superclass.prototype; subclass.prototype = new F(); subclass.prototype.constructor = subclass; subclass.super = superclass.prototype; if (superclass.prototype.constructor === Object.prototype.constructor) { superclass.prototype.constructor = superclass; }}function override(targetObj, obj, deep) { if (Object.prototype.toString.call(obj) !== \\\&#039;[object Object]\\\&#039;) { return; } for (var i in obj) { if (obj.hasOwnProperty(i)) { if (deep === true) { targetObj[i] = targetObj[i] || {}; rewrite(targetObj[i], obj[i], deep); } else { targetObj[i] = obj[i]; } } }}中介者模式 定义: 用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 本质:封装交互 中介者模式的解决私立很简单,它通过引入一个中介对象,让其他的对象都只和中介对象交互,而中介对象知道如何和其他所有的对象交互 [check](https://alaudio.com.sg/new-arrival-dali-oberon-series/ check),这样对象之间的交互关系就没有了,从而实现了对象之间的解耦。 对于中介对象而言,所有的相互交互的对象,被视为同事类,中介者对象就是来维护各个同事之间的关系,而所有的同事类都只是和中介对象交互。 每个同事对象,当自己发生变化的时候,不需要知道这会引起其他对象有什么变化,它只需要通知中介者就可以了,然后由中介者去与其他对象交互。这样松散耦合带来的好处是,除了让同事对象之间相互没有关联外,还有利于功能的修改和扩展。 有了中介者之后,所有的交互都封装到中介者对象里面,各个对象就不再需要维护这些关系了。扩展关系的时候也只需要扩展或修改中介者对象就可以了。 同事关系 在标准的中介者模式中,将使用中介者对象来交互的那些对象称为同事类,在中介者模式中,要求这些类都要继承相同的类。也就是说,这些对象从某个角度讲是同一个类型,算是兄弟对象。 正是这些兄弟对象之间的交互关系很复杂,才产生了把这些交互关系分离出来,单独做成中介者对象。 同事和中介者的关系 在中介者模式中,当一个同事对象发生了改变,需要主动通知中介者,让中介者去处理与其他同事对象相关的交互。 这就导致了同事对象和中介者对象之间必须有关系,首先是同事对象需要知道中介者对象是谁;反过来,中介者对象也需要知道相关的同事对象,这样它才能与同事对象进行交互。也就是说中介者对象和同事对象之间是相互依赖的。 如何实现同事和中介者的通信 一个同事对象发生了改变,会通知中介者对象,中介者对象会处理与其他同事的交互,这就产生了同事对象和中介者对象的相互通信。 一个实现方式是在Mediator接口中定义一个特殊的通知接口,作为一个通用的方法,让各个同事类来调用这个方法,在中介者模式结构图里画的就是这种方式。例如定义了一个通用的changed方法,并且把同事对象当作参数传入,这样在中介者对象里面,就可以去获取这个同事对象的实例数据了。 另外一种实现方式是可以采用观察者模式,把Mediator实现成为观察者,而各个同事类实现成为Subject,这样同事类发生了改变,会通知Mediator。Mediator在接到通知以后,会于相应的同事对象进行交互。 示例代码: (function(){ function Colleague(mediator){ this.mediator = mediator;}Colleague.prototype = { getMediator: function(){ return this.mediator; }}; // 同事类Afunction ColleagueA(mediator){ ColleagueA.super.constructor.apply(this, arguments);}extend(ColleagueA, Colleague);ColleagueA.prototype.someOperation= function(){ // some code.. // 在需要跟其他同事通信的时候,通知中介者对象 this.getMediator().changed(this);} function ColleagueB(mediator){ ColleagueB.super.constructor.call(this);}extend(ColleagueB, Colleague);ColleagueB.prototype.someOperation= function(){ // some code.. // 在需要跟其他同事通信的时候,通知中介者对象 this.getMediator().changed(this);}; // 中介者function Mediator(){ var colleagueA, colleagueB; // 设置中介者需要了解并维护的同事A对象 this.setColleagueA = function(colleague){ colleagueA = colleague; }; // 设置中介者需要了解并维护的同事B对象 this.setColleagueB = function(colleague){ colleagueB = colleague; }; this.changed = function(colleague){ // 某个同事类发生了变化,通常需要与其他同事交互 // 具体协调相应的同事对象来实现协作行为 };}}()); (function(){ // 抽象同事类 var Colleague = function(mediator){ this.mediator = mediator; }; Colleague.prototype = { getMediator: function(){ return this.mediator; } }; // 光驱类 var CDDriver = function(){ CDDriver.super.constructor.apply(this, arguments); this.data = \\\&#039;\\\&#039;; }; extend(CDDriver, Colleague); override(CDDriver.prototype, { getData: function(){ return this.data; }, readCD: function(){ this.data = \\\&#039;CDDriver Data, SoundCard Data\\\&#039;; // 通知主板,自己的状态发生了变化 this.getMediator().changed(this); } }); // CPU类 var CPU = function(){ CPU.super.constructor.apply(this, arguments); this.videoData = \\\&#039;\\\&#039;; this.soundData = \\\&#039;\\\&#039;; }; extend(CPU, Colleague); override(CPU.prototype, { // 获取分解出来的视频数据 getVideoData: function(){ return this.videoData; }, // 获取分解出来的声音数据 getSoundData: function(){ return this.soundData; }, executeData: function(data){ var ss = data.split(\\\&#039;,\\\&#039;); this.videoData = ss[0]; this.soundData = ss[1]; // 通知主板,CPU的工作完成 this.getMediator().changed(this); } }); // 显卡类 var VideoCard = function(){ VideoCard.super.constructor.apply(this, arguments); }; extend(VideoCard, Colleague); override(VideoCard.prototype, { showData: function(data){ console.log(\\\&#039;您正在观看的是:\\\&#039; + data); } }); // 声卡类 var SoundCard = function(){ SoundCard.super.constructor.apply(this, arguments); }; extend(SoundCard, Colleague); override(SoundCard.prototype, { soundData: function(data){ console.log(\\\&#039;画外音:\\\&#039; + data); } }); // 中介对象接口 var Mediator = function(){}; Mediator.prototype = { changed: function(colleague){} }; var MotherBoard = function(){ }; extend(MotherBoard, Mediator); override(MotherBoard.prototype, { setCdDriver: function(cdDriver){ this.cdDriver = cdDriver; }, setCpu: function(cpu){ this.cpu = cpu; }, setVideoCard: function(videoCard){ this.videoCard = videoCard; }, setSoundCard: function(soundCard){ this.soundCard = soundCard; }, changed: function(colleague){ switch(colleague) { case this.cdDriver: this.opeCDDriverReadData(colleague); break; case this.cpu: this.opeCPU(colleague); break; default: break; } }, opeCDDriverReadData: function(cd){ this.cpu.executeData(cd.getData()); }, opeCPU: function(cpu){ this.videoCard.showData(cpu.getVideoData()); this.soundCard.soundData(cpu.getSoundData()); } }); void function run(){ var mediator = new MotherBoard(); var cd = new CDDriver(mediator); var cpu = new CPU(mediator); var vc = new VideoCard(mediator); var sc = new SoundCard(mediator); mediator.setCdDriver(cd); mediator.setCpu(cpu); mediator.setVideoCard(vc); mediator.setSoundCard(sc); cd.readCD(); }(); }());广义中介者 在实际开发中,经常会简化中介者模式,比如有如下简化: 1.通常会去掉同事对象的父类,这样可以让人意的对象,只要需要相互交互,就可以成为同事。 2.通常不定义Mediator接口,把具体的中介者对象实现成为单例。 3.同事对象不再持有中介者,而是在需要的时候直接获取中介者对象并调用;中介者也不再持有同事对象,而是在具体处理方法里面去创建,或者获取,或者从参数传入需要的同事对象。 // 部门与人员的交互(function(){ // 部门类 var Dep = function(){ // 描述部门编号 this.depId = \\\&#039;\\\&#039;; // 描述部门名称 this.depName = \\\&#039;\\\&#039;; }; Dep.prototype = { getDepId: function(){ return this.depId; }, setDepId: function(depId){ this.depId = depId; }, getDepName: function(){ return this.depName; }, setDepName: function(depName){ this.depName = depName; }, // 撤销部门 deleteDep: function(){ // 要先通过中介者去除掉所有与这个部门相关的部门和人员的关系。 var mediator = DepUserMediatorImpl.getInstance(); mediator.deleteDep(this.depId); // 然后才能真正地清除掉这个部门 // 在实际开发中,这些业务功能可能会做到业务层去 // 而且实际开发中对于已经使用的业务数据通常不会被删除 // 而是会被作为历史数据保留 return true; } }; // 人员类 var User = function(){ // 人员编号 this.userId = \\\&#039;\\\&#039;; // 人员名称 this.userName = \\\&#039;\\\&#039;; }; User.prototype = { getUserId: function(){ return this.userId; }, setUserId: function(userId){ this.userId = userId; }, getUserName: function(){ return this.userName; }, setUserName: function(userName){ this.userName = userName; }, // 人员离职 dimission: function(){ var mediator = DepUserMediatorImpl.getInstance(); mediator.deleteUser(this.userId); return true; } }; // 描述部门和人员关系的类 var DepUserModel = function(){ // 用于部门和人员关系的编号,用作主键 this.depUserId = \\\&#039;\\\&#039;; this.depId = \\\&#039;\\\&#039;; this.userId = \\\&#039;\\\&#039;; }; DepUserModel.prototype = { setDepUserId: function(depUserId){ this.depUserId = depUserId; }, getDepUserId: function(){ return this.depUserId; }, setDepId: function(depId){ this.depId = depId; }, getDepId: function(){ return this.depId; }, setUserId: function(userId){ this.userId = userId; }, getUserId: function(){ return this.userId; } }; // 中介者对象 var DepUserMediatorImpl = function(){ // 记录部门和人员的关系 this.depUserCol = []; this.initTestData(); }; DepUserMediatorImpl.getInstance = function(){ if(!(DepUserMediatorImpl.instance instanceof DepUserMediatorImpl)) { DepUserMediatorImpl.instance = new DepUserMediatorImpl(); } return DepUserMediatorImpl.instance; }; DepUserMediatorImpl.prototype = { // 初始化测试数据 initTestData: function(){ var du1 = new DepUserModel(); du1.setDepUserId(\\\&#039;du1\\\&#039;); du1.setDepId(\\\&#039;d1\\\&#039;); du1.setUserId(\\\&#039;u1\\\&#039;); this.depUserCol.push(du1); var du2 = new DepUserModel(); du2.setDepUserId(\\\&#039;du2\\\&#039;); du2.setDepId(\\\&#039;d1\\\&#039;); du2.setUserId(\\\&#039;u2\\\&#039;); this.depUserCol.push(du2); var du3 = new DepUserModel(); du3.setDepUserId(\\\&#039;du3\\\&#039;); du3.setDepId(\\\&#039;d2\\\&#039;); du3.setUserId(\\\&#039;u3\\\&#039;); this.depUserCol.push(du3); var du4 = new DepUserModel(); du4.setDepUserId(\\\&#039;du4\\\&#039;); du4.setDepId(\\\&#039;d2\\\&#039;); du4.setUserId(\\\&#039;u4\\\&#039;); this.depUserCol.push(du4); var du5 = new DepUserModel(); du5.setDepUserId(\\\&#039;du5\\\&#039;); du5.setDepId(\\\&#039;d2\\\&#039;); du5.setUserId(\\\&#039;u1\\\&#039;); this.depUserCol.push(du5); }, // 完成因撤销部门的操作所引起的与人员的交互,需要去除相应的关系 deleteDep: function(depId){ for(var i = 0; i 中介者模式的优点:1.松散耦合中介者模式用过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互不依赖。这样一来,同事对象就可以独立变化和复用,从而不再像以前那样“牵一发而动全身”。2.集中控制交互多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那就扩展中介者对象,而各个同事类不需要做修改。3.多对多变成一对多没有使用中介者模式的时候,同事对象之间的关系通常是多对多的,引入中介者对象之后,中介者对象和同事对象的关系通常变成了双向的一对多,这会让对象的关系更让哦难以理解和实现。中介者模式的缺点:1.过度集中化如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到中介者的时候,会导致中介者对象变得十分复杂,而且难于管理和维护。何时选用中介者模式1.如果一组对象之间的通信比较复杂,导致相互依赖,结构混乱,可以采用中介者模式,吧这些对象相互的交互管理起来,各个对象都只需要和中介者交互,从而使得各个对象松散耦合,结构也更清晰易懂。2.如果一个对象引用很多对象,并直接跟这些对象交互,导致难以复用该对象,可以采用中介者模式,把这个对象跟其他对象的交互封装到中介者对象里面,这个对象只需要和中介者对象交互就可以了。相关模式中介者模式和外观模式这两个模式有相似的地方,也存在很大的不同。外观模式多用来封装一个子系统内部的多个模块,目的是想子系统外部提供简单易用的接口。也就是说外观模式封装的是子系统外部和子系统内部模块间的交互;而中介者模式是提供多个平等的同事对象之间交互关系的封装,一般是用在内部实现上。另外,外观模式是实现单向的交互,是从子系统外部来调用子系统内部,不会反着来;而中介者模式实现的是内部多个模块间多向的交互。中介者模式和观察者模式这两个模式可以组合使用。中介者模式可以组合使用观察者模式,来实现当同事对象发生改变的时候,通知中介者对象,让中介对象去进行与其他相关对象的交互。// example/ Title: Mediator Description: allows loose coupling between classes by being the only class that has detailed knowledge of their methods / (function(){ function Player(name) { this.points = 0; this.name = name;}Player.prototype.play = function () { this.points += 1; mediator.played();};var scoreboard = { // HTML element to be updated element:document.getElementById(\\'results\\'), // update the score display update:function (score) { var i, msg = \\'\\'; for (i in score) { if (score.hasOwnProperty(i)) { msg += \\' \\' + i + \\': \\'; msg += score[i]; msg += \\'\\'; } } this.element.innerHTML = msg; }}; var mediator = { // all the player players:{}, // initialization setup:function () { var players = this.players; players.home = new Player(\\'Home\\'); players.guest = new Player(\\'Guest\\'); }, // someone plays, update the score played:function () { var players = this.players, score = { Home:players.home.points, Guest:players.guest.points }; scoreboard.update(score); }, // handle user interactions keypress:function (e) { e = e || window.event; // IE if (e.which === 49) { // key 1 mediator.players.home.play(); return; } if (e.which === 48) { // key 0 mediator.players.guest.play(); return; } }}; // go!mediator.setup();window.onkeypress = mediator.keypress; // game over in 30 secondssetTimeout(function () { window.onkeypress = null; console.log(\\'Game over!\\');}, 30000);}()); <code>// http://www.dofactory.com/javascript-mediator-pattern.aspx(function () { var Participant = function (name) { this.name = name; this.chatroom = null; }; Participant.prototype = { send: function (message, to) { this.chatroom.send(message, this, to); }, receive: function (message, from) { log.add(from.name + to + this.name + : + message); } }; var Chatroom = function () { var participants = {}; return { register: function (participant) { participants[participant.name] = participant; participant.chatroom = this; }, send: function (message, from, to) { if (to) { // single message to.receive(message, from); } else { // broadcast message for (key in participants) { if (participants[key] !== from) { participants[key].receive(message, from); } } } } }; }; // log helper var log = (function () { var log = ; return { add: function (msg) { log += msg + \\\\n; }, show: function () { alert(log); log = ; } } })(); function run() { var yoko = new Participant(Yoko); var john = new Participant(John); var paul = new Participant(Paul); var ringo = new Participant(Ringo); var chatroom = new Chatroom(); chatroom.register(yoko); chatroom.register(john); chatroom.register(paul); chatroom.register(ringo); yoko.send(All you need is love.); yoko.send(I love you John.); john.send(Hey, no need to broadcast, yoko); paul.send(Ha, I heard that!); ringo.send(Paul, what do you think?, paul); log.show(); }}());// example/* Title: Mediator Description: allows loose coupling between classes by being the only class that has detailed knowledge of their methods */文章来源:http://www.cnblogs.com/webFrontDev/p/3553400.html作者:luke_ldp

生成器模式(Builder)


function extend(subclass, superclass) {
var F = function () {
};
F.prototype = superclass.prototype;
subclass.prototype = new F();
subclass.prototype.constructor = subclass;
subclass.super = superclass.prototype;

if (superclass.prototype.constructor === Object.prototype.constructor) {
superclass.prototype.constructor = superclass;
}
}

function mixin(targetObj, obj, deep) {
if (Object.prototype.toString.call(obj) !== '[object Object]') {
return;
}
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (deep === true) {
targetObj[i] = targetObj[i] || {};
mixin(targetObj[i], obj[i], deep);
} else {
targetObj[i] = obj[i];
}
}
}
}

<script></script>
生成器模式

定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

本质:
分离整体构建算法和部件构造。
生成器模式的重心在于分离整体构建算法和部件构造,而分步骤构建对象不过是整体构建算法的一个简单实现,或者说是一个附带产物。

要实现同样的构建过程可以创建不同的表现,那么一个自然的思路就是先把构建过程独立出来,在生成器模式中把它称为指导者,由它来指导装配过程,但是不负责每步具体的实现。当然,光有指导者是不够的,必须要有能具体实现每步的对象,在生成器模式中称这些实现对象为生成器。
这样一来,指导者就是可以重用的构建过程,而生成器是可以被切换的具体实现。
继续阅读生成器模式(Builder)

匿名函数块级作用域以及在JQuery中的应用

最近经常回在群里面看到有些朋友问如下这样的js写法该如何理解的的问题,虽然可能对匿名函数有些理解,但是有时候看到JQuery源码或者其他JS库中同样的写法时,就有点不理解了,今天再次分享下这方面的知识点。

(function(){

})(JQuery);

对以上写法的理解:

上面的这种写法通常叫做“块级作用域”,块级作用域的好处就是可以将匿名方法内部的变量进行私有化,当程序运行结束之后便将一些变量自动销毁。第一个()号表示次函数为一个函数表达式,其中包含了一个匿名函数,后面的一个()则表示执行这个函数表达式中的匿名方法,而JQuery则作为这个匿名函数的一个参数。bondage wiki bdsmvids.net

继续阅读匿名函数块级作用域以及在JQuery中的应用

不错的javascript工厂案例(Abstract Factory)

文章来自:http://www.dofactory.com/javascript-abstract-factory-pattern.aspx

Definition

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Frequency of use (in JavaScript):    high   medium

 

Summary

An Abstract Factory creates objects that are related by a common theme. In object-oriented programming a Factory is an object that creates other objects. An Abstract Factory has abstracted out a theme which is shared by the newly created objects.

继续阅读不错的javascript工厂案例(Abstract Factory)

提高 web 应用性能之 JavaScript 性能调优

文章来自 IBM developerWorks

Web 开发中经常会遇到性能的问题,尤其是针对当今的 Web2.0 应用。JavaScript 是当今使用最为广泛的 Web 开发语言,Web 应用的性能问题很大一部分都是由程序员写的 JavaScript 脚本性能不佳所造成的,里面包括了 JavaScript 语言本身的性能问题,以及其与 DOM 交互时的性能问题。本文主要来探讨一下如何尽可能多的避免这类问题,从而最大限度的提高 Web 应用的性能。

JavaScript 性能调优

JavaScript 语言由于它的单线程和解释执行的两个特点,决定了它本身有很多地方有性能问题,所以可改进的地方有不少。

eval 的问题:

比较下述代码:

清单 1. eval 的问题

				 
 var reference = {}, props = “p1”; 
 eval(“reference.” + props + “=5”) 

 var reference = {}, props = “p1”; 
 reference[props] = 5

有“eval”的代码比没有“eval”的代码要慢上 100 倍以上。

主要原因是:JavaScript 代码在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用 var 申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是 undefined,并将那些以 function 定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。但是,如果你使用了“eval”,则“eval”中的代码(实际上为字符串)无法预先识 别其上下文,无法被提前解析和优化,即无法进行预编译的操作。所以,其性能也会大幅度降低。

继续阅读提高 web 应用性能之 JavaScript 性能调优

分析JavaScript的性能

Kirk Pepperdine在一篇新文章中详细讨论了关于JavaScript性能的主题。他的第一个发现是JavaScript引擎规范要比JVM的脆弱的多。有太多的JavaScript实现,各自具有不同的执行环境。除了这一点外,他还深入了下列主题:

    Getters/Setters

    ……我所遭遇的最具争议的一项建议,在Java世界里已经很久没人提起过了。这项建议是,应该避免使用getter和setter,而应当采用直接访问来避免方法调用的额外开销。这项建议错在哪里?更重要的是,它对在哪里?在Java中使用getter和setter是被普遍认可的……

    Ajaxian和JQuery的创建者John Resig曾经讨论过getter和setter。就像这个网站所演示的,是出于性能上的考虑。

    由于缓存造成的糟糕的局部基准评测(Micro-benchmark

    ……由于JavaScript引擎中少得多的动态优化,有人会觉得局部基准评测要比在Java中容易得多。虽然问题是不同的,但是JavaScript的局部基准评测也没那么容易。糟糕的局部基准评测的最普遍的原因是缓存。在Web世界中缓存无处不在,伴随始终。而且通常它隐藏的很深……

继续阅读分析JavaScript的性能

CSS语义化标准化命名规则

CSS语义化标准化命名规则

一般而言,CSS类名的语义化声明方式应当考虑你的页面中某个相对元素的”用意”,独立于它的”定位”或确切的特性(结构化方式)。像left-bar, red-text, small-title…这些都属于结构化定义的例子。

让我们看看下面这个例子:

 

继续阅读CSS语义化标准化命名规则

Log4Net使用指南

声明:本文内容主要译自Nauman Leghari的Using log4net,亦加入了个人的一点心得(节3.1.4)。
请在这里下载示例代码

1 简介

1.1 Log4net的优点:

几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。

经验表明,日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点:它可以提供应用程序运行时的精确环境,可供开发人员尽快找到应用程序中的Bug;一旦在程序中加入了Log 输出代码,程序运行过程中就能生成并输出日志信息而无需人工干预。另外,日志信息可以输出到不同的地方(控制台,文件等)以备以后研究之用。

Log4net就是为这样一个目的设计的,用于.NET开发环境的日志记录包。

1.2 Log4net的安装:

用户可以从http://logging.apache.org/log4net/下载log4net的源代码。解压软件包后,在解压的src目录下将log4net.sln载入Visual Studio .NET,编译后可以得到log4net.dll。用户要在自己的程序里加入日志功能,只需将log4net.dll引入工程即可。

 

2 Log4net的结构

log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局).

2.1 Logger

2.1.1 Logger接口

Logger是应用程序需要交互的主要组件,它用来产生日志消息。产生的日志消息并不直接显示,还要预先经过Layout的格式化处理后才会输出。

Logger提供了多种方式来记录一个日志消息,你可以在你的应用程序里创建多个Logger,每个实例化的Logger对象都被log4net框架作为命名实体(named entity)来维护。这意味着为了重用Logger对象,你不必将它在不同的类或对象间传递,只需要用它的名字为参数调用就可以了。log4net框架使用继承体系,继承体系类似于.NET中的名字空间。也就是说,如果有两个logger,分别被定义为a.b.c和a.b,那么我们说a.b是a.b.c的祖先。每一个logger都继承了祖先的属性 继续阅读Log4Net使用指南