精简公理:
1. 当一个非空的接口指针从一个内存位置被拷贝到另一个内存位置时,应该要调用AddRef,以便通知对象又有附加的引用发生了。
2.对于已经包含非空接口指针的内存位置来说,在重写该内存位置之前,必须先调用Release, 以便通知对象“这个引用已经被销毁了”。
3.如果你对两个或者更多的内存位置之间的关系有特殊的理解,那么多余的AddRef和Release调用可以被优化掉。
编程指导:
A.要求调用AddRef的情形:
A1.当把一个非空接口指针写到局部变量中时。
A2.当被调用方把一个非空接口指针写到方法或者函数的[out]或者[in,out]参数中时。
A3.当被调用方返回一个非空接口指针作为函数的实际接口时。
A4.当把一个非空接口指针写到对象的一个数据成员中时。
R.要求调用Release方法的情形:
R1.在改写一个非空局部变量或者数据成员之前。
R2.在离开非空局部变量的作用域之前。
R3.当被调用方要改写方法或者函数的[in,out]参数,并且参数的初始值为非空时([out]参数不适用)。
R4.在改写一个对象的非空数据成员之前。
R5.在离开一个对象的析构函数之前,并且这时还有一个非空接口指针作为数据成员。
特殊情况:
S1.当调用方把一个非空接口指针通过[in]参数传给一个函数或者方法时,既不需要调用AddRef,也不需要调用Release,因为在调用堆栈中,临时变量的生命周期只是“用于初始化形式参数”的表达式地生命周期的一个子集。
posted @
2010-03-13 08:50 RUI 阅读(547) |
评论 (0) |
编辑 收藏
可遍历的调用栈:(arguments.callee, arguments.callee.caller)
某函数被调用时刻:
function _A(){
_stack_push()
F.arguments = new BaseArray(x,y,z...);
F.arguments.callee = F;
F.caller = _A;
执行 F...
_stack_pop()
}
虽然可以利用 callee,caller进行调用栈遍历,但是可能发生死循环!
1 function enumStack(callback)
2 {
3 var f = arguments.callee;
4 while (f.caller)
5 {
6 callback(f = f.caller);
7 }
8 }
9 var _r_f = /^function \b\s*([$\w\u00FF-\uFFFF]+)\s*\(/m;
10 function showIt(func){
11 var name = (!(func instanceof Function)? 'unknow type':_r_f.test(func.toString()) ? RegExp.$1:'anonymous');
12 alert('-> ' + name);
13 }
14
15 var i = 0;
16 var i_max = 1; // i_max > 1 时发生死循环
17 function f1()
18 {
19 f2();
20 }
21
22 function f2()
23 {
24 if (++i <i_max){
25 f1();
26 }
27 enumStack(showIt);
28 }
29
30 f1();
1 function enumStack(callback)
2 {
3 var f = arguments.callee;
4 while (f.caller)
5 {
6 callback(f = f.caller);
7 }
8 }
9 var _r_f = /^function \b\s*([$\w\u00FF-\uFFFF]+)\s*\(/m;
10 function showIt(func){
11 var name = (!(func instanceof Function)? 'unknow type':_r_f.test(func.toString()) ? RegExp.$1:'anonymous');
12 alert('-> ' + name);
13 }
14
15 var i = 0;
16 var i_max = 1; // i_max > 1 时发生死循环
17 function f1()
18 {
19 f2();
20 }
21
22 function f2()
23 {
24 if (++i <i_max){
25 f1();
26 }
27 enumStack(showIt);
28 }
29
30 f1();闭包:javascript中有两种闭包,一种为函数闭包,一种为对象闭包(with语句);函数闭包是与函数执行过程成对出现的数据,它在函数运行结束后,保持运行过程的最终数据状态。闭包包括的是函数运行实例的引用、环境、以及一个由所有upvalue引用组成的数组,由此可知
1 function MyObject(){
2 function func(){}
3 return func;
4 }
5 var obj1 = MyObject();
6 var obj2 = MyObject();
7 obj1 != obj2 //!!!!!!!!!!!!!
obj1.toString() == obj2.toString() //!!!!!!!!!!!!!!!!!!!
在被调用时(函数运行产生函数实例
),每个函数实例至少拥有一个闭包,也可能有多个:
var checker;
function myFunc()
{
if (checker){
checker();
}
alert('do myFunc: ' + str);
var str = 'test.';
if (!checker){
checker = function(){alert('do Check : ' + str);}
}
return arguments.callee;
}
myFunc()();//myFunc();myFunc()
//do myFunc: undefined
//do Check: test. 第二个闭包生效
//do myFunc: undefined
javascript 执行环境描述如下:
TheContext = {type:'Function', name:'myFunc', params:[...], body:ScriptObject}; ScriptOjbect = {type:'SCRIPT', varDecls:[...], funcDecls:[....], source:'....'}, TheContext结构描述函数作为对象时的外在表现,如函数名,参数,等等。其body指向一个ScriptObject, 这个ScriptObject就包含了函数代码体中的全部语法分析结构,包括内部变量表和内嵌函数表以及除此之外的全部代码。此外还有两个概念即 调用对象和全局对象;调用对象是指当前正在调用函数的ScriptObject结构;而全局对象是指系统全局环境下的一个ScriptObject结构。全局变量就是全局对象的属性,局部变量就是调用对象的属性。
变量(闭包)的维护规则:
1.在函数开始执行时,varDecls中所有的值将被置为undefined, varDecls总是在语法分析阶段被创建好
2.函数执行结束并退出时,varDecls不被重置。
3.函数内的数据持续的生存周期,取决于该函数实例是否为活动引用,如果没有,则调用对象可被销毁。
4.全局对象的相应动作同理
调用对象在语法分析期可以得到,以其ScriptObject作为原型,接下来在函数运行期若该函数实例有一个函数闭包,则引擎将会:
1.创建一个函数实例
2.为该函数创建一个闭包
3.为该函数实例(及其闭包)的运行环境从ScriptObject复制一个‘调用对象’
闭包中标识符的优先级:
this > 局部变量(varDecls) > 函数形式参数名(argsName) > ( (arguments > 函数名(funcName)) FireFox || (arguments > 函数名(funcName)) IE)
function foo(foo){
alert(foo);
}
foo('hi') // alert('hi');
////////////////////
function foo2(arguments){
alert(typeof arguments);
}
foo2(1000);//'number'
/////////////////////
function arguments(){
alert(typeof arguments);
}
//function ==> IE JScript
//object FireFox SpiderMonkey
arguments();
由Function()构造出来的函数对象与函数直接量声明,匿名函数不同,它在任意位置创建的实例,都处于全局闭包中!Function()的实例的upvalue总是指向全局闭包,所以不会对其他闭包内的变量产生引用!!
1 var val = 'this is global.'
2 function my(){
3 var val = 'this is local.'
4 var foo = new Function('\
5 alert(val);\ // 这里会被toString
6 ');
7 foo(); // 'this is global.
8 }
所谓对象闭包是指使用with语句时与with()所指示对象相关的闭包,该闭包被动态创建并添加到执行环境当前闭包链顶端:
(IE 和 FireFox)
1 var aObj = {val:'hello'}
2 function foo(){
3 with(aObj)
4 {
5 var val = 1000; //声明局部变量val, 运行时为aObj.val 赋值
6 alert(aObj.val); // 1000
7 }
8 alert(val) //undefined
9 }
10 foo();
11
具名函数的闭包与对象闭包
1 var obj = { val:200};
2 var val =1000;
3 with(obj){
4 function foo(){val*=2;}//具名函数的闭包依赖于函数静态位置所决定; 语法分析期决定 obj对象闭包与foo()函数闭包处于并列位置
5 foo();
6 }
7 alert(obj.val); // 200
8 alert(val); // 2000
9
匿名函数闭包与对象闭包
var obj = { val:200};
var val =1000;
with(obj){
void function(){val*=2;}();//匿名函数的闭包依赖于其所在的当前闭包链
/*
var a = function(){val*=2;};//匿名函数的闭包依赖于其所在的当前闭包链
a();
*/
}
alert(obj.val); // 400
alert(val); // 1000
eg2:
function foo(){
function foo2(){
var msg = 'hello';
m = function (varName){return eval(varName);}
}
foo2();
var aFormatStr = 'the value is : ${msg}';
var m;
var rx = /\$\{(.*?)\}/g;
alert(aFormatStr.replace(rx, function($0, varName){return m(varName);}));
}
foo(); // alert('the value is : hello');
eval()与闭包 (使用当前函数的闭包)
1 var i = 100;
2 function f(){
3 var i = 'test';
4 eval('i="hello"');
5 }
6 f();
7
8 alert(i); // 100
var i = 100;
function my(){
eval('var i = "eee"');
return i
}
alert(my());// alert('eee')
若使用 window.eval() 则IE 和 Firefox 不一致
1 var i = 100;
2 function f(){
3 var i = 'test';
4 window.eval('i="hello"'); // eval.call(window, 'i="hello"');
5 }
6 f();
7
8 alert(i); // IE为100, Firefox为hello
9 //IE 为了函数内执行的eval()尽量不产生副作用, 即eval访问不到全局的闭包 但window.execScript()总是在全局闭包中 (Firefox 没有这个函数)
// execScript()的第二个参数为脚本语言的种类 eg: 'JScript', 'VBScript', 'Python', 'Lua' (FireFox 中的eval有2个参数)
eval('..')总是试图返回值,由被执行代码块的最后一个语句决定 alert(eval('for(var i = 0; i < 10; ++i)')) //alert('undefined')
也就是说 eval('..')的返回值是javascript中语句的副作用导致的结果,eval本质是一个动态的语句执行系统。
所以我们可以用 var b = eval('true');得到一个布尔值,却不能用var ob = eval('{b:true, i:1}');得到一个直接量,因为其内容不是合法
语句,而eval('{b:1}');返回值确是1, ‘b:'被当作标签声明。
解决方法是使用强制表达式运算符'()': 如下 eval('({b:true,i:1})') 但是在IE(JScript)中存在一个例外:函数直接量(匿名函数)不能通过这种方式来获得 eval('(function(){})') == undefined ; 但可以这样 eval('([function(){}][0])')
eval的存在也倒是javascript代码是不可编译的(二进制的,而非虚拟机代码)
javascript动态方法调用:
javascript中有三种执行体:一种是eval()函数入口参数中指定的字符串,该字符串总是被作为当前函数上下文中的语句来执行;第二种是new Function()中传入的字符串,该字符串总是被作为一个全局的,匿名函数闭包中的语句行被执行;第三种情况,执行体就是一个函数,可以通过函数调用运算符"()"来执行,也可以通过apply(this,array or argument),或者 call(this,$0,$1,..);两者区别在于参数不同,且apply做了优化。它们主要是用来改变function中this引用的。 若第一参数为null或undefined表明执行中传入默认的宿主对象。
用eval来模拟Function.call 和 Function.apply
1 Fucntion.prototype.apply = function(thisArg, argArray){
2 thisArg = (thisArg==null)?window:Object(thisArg);
3 thisArg.__applyTemp__=this;
4 var parameters = [], length=(argArray || '').length;
5 for(var i = 0; i < length; ++i) parameters[i]='argArray['+i+']';
6
7 var functionCall = 'thisArg.__applyTemp__('+parameters+')';
8 try{ return eval(functionCall)}
9 finally{try{delete thisArg.__applyTemp__}catch(e){}
10 }
11 }
12
13 Function.prototype.call=function(thisArg){
14 return this.apply(thisArg,
15 Array.prototype.slice.apply(arguments,1));
16 }
17
18 }
19 }
javascript中的重写:
javascript中包括原型重写(完全重写后改变构造器!!),构造器重写, 对象成员重写。如果构造器在运行时刻被覆盖,将会给对象检测带来麻烦!
eg1:
function F(){}
var a = new F();
function F(){this.name="myF"} //这种情况的重写发生在语法分析阶段,导致全局只有一个F()存在,即第二个声明,同时a.name == "myF"
eg2:
function F(){}
var a = new F();
F = function(){this.name="myF"}//这种情况的重写发生在运行阶段,从此处开始,到变量F的作用域结束,其覆盖同名函数,所以a.name == undefined
对象成员重写可以用 hasOwnProperty来里检测,该方法不检查一个实例的父类代码,或原型代码
posted @
2009-10-25 18:44 RUI 阅读(349) |
评论 (0) |
编辑 收藏
基本数据类型:
1. undefined 2.number 3.boolean 4.string 5.function 6.object, 其中function, object 为引用类型
检测一个变量是否存在 typeof(aVar) == 'undefined'
javascript 中字符串为Unicode字符序列, 反斜杠'\'当位于一行的末尾时,用于表示连续字符串声明. '\0'并不代表字符串的结束,如 var a = 'abc\0d'; 表示为'abc d', 空字符串 '' 也可以作为对象成员 如: var obj = {'':100};
函数直接量:
在SpiderMokey Javascript中,表达式中的具名函数只识别为匿名函数,而忽略函数名,而JS中则不同.如下:
(
function foo()
{alert(1);}
);
alert(foo); //在IE中可执行,但在FireFox下有语法错误 foo 为定义。
函数的定义:
function f(){alert(1);};
var f = function(){alert(1);}
var f = Function('alert(1);');
var f = new Function('alert(1);');
匿名函数的调用方式://没有引用的匿名函数的调用
1. (function(){alert(1);}()); //最外层()为强制运算符,其内部为函数调用,返回函数执行结果
2. (function(){alert(1);})();
//前面的()为强制运算符,返回匿名函数, 而后函数被调用
3. void function(){alert(1);}(); //一定要有 void,其使其后的函数表达式执行运算
强制运算符 () 与 void 确保以上脚本通过引擎的语法检测,负责 函数调用的那对() 是非法的, '();'单独存在没有意义。 同时他们也使得函数声明变成‘直接量的单值表达式’而被执行。
正则表达式:
var reg = /ab\nc/gi 等价于 var reg = new RegExp('ab\\nc','gi');
运算符:
typeof 取变量的类型(6种之一)
void 使被修饰的表达式返回undefined; void (1+2) 返回undefined
new 创建对象, new Object 等价于 new Object(), 因为Object的contructor无arguments
function B()
{
}
fuction A()
{
return new B();
}
var b = new A //new A(); 返回B的实例
function getClass()
{return A;}
var b = new (getClass());
in 枚举对象属性; 属性检测
instanceof 检查变量是否为指定类的实例
delete 删除实例的属性,若成功则返回true, 但不能删除1.用var声明的变量 2.直接继承自原型的成员
&& || 具有短路效应,且返回值不一定为boolean, 如: 'abc' || 32 返回 'abc'; 'abc' && 32 返回 32
javascript没有goto语句,但有带标号语句的break 和continue (抄袭java的)
javascript中的异常捕获:
try
{
}
catch(e)
{
}
finally
{
}
javascript中的with 语句://指定当前环境的默认对象,否则为window
function A()
{
this.ii = 10;
}
;
var a = new A();
var ii = 1000;
with(a)
{
alert(ii);//10
}
关于javascript中的 ';'
换行符和文本结束符的前面可以没有分号,即:
var a = 1
alert (a) 合法
但 var a = 1 alert(a) // 语法错误
注意javascript中的变量只能达到函数级别 所以下列语句合法
for(var i = 0; i < 1; ++i);
alert(i);
Javascript 中的对象:
1. 利用构造函数创建对象 function a(){}; var b = new a;
2. 对象直接量声明 var obj = {name:'hi','1':'1','abc.def':'aaa',,,,} //其中属性名可以是合法的标示符 或者 字符串,数字
访问方式 obj.标识符,obj.字符串值(合法标示符),obj['标识符'], obj[数字],obj['数字'] ,obj[字符串]
3. 对象成员的可枚举性 for(var prop in obj) 是否能够枚举: 可以调用 propertyIsEnumerable 进行测试, 但原型继承链中的属性 会返回false,但却能被 for(var prop in obj) 枚举
如:
var obj = new Object(); obj.name='name'; obj.propertyIsEnumerable('name') //true ; obj.propertyIsEnumerable('no')//false
obj.propertyIsEnumerable('toString') //false 内置成员不可枚举
a[[1][1]] == a[undefined] ==> arr = [1], a[arr[1]] = a[undefined]
javascript 引擎之WScript
/*fileanme: argus_ws.js*/
function alert(str){WScript.echo(str);}
alert(WScript.Arguments.Length);
alert(WScript.Arguments(0));
javascript中的变量声明和定义:
a.当引擎发现 var 声明的变量时,在其作用域中声明它,并设置为undefined, 此时并没有初始化动作
b.当引擎发现 某个非var变量被赋值,则解析它为全局变量
alert(a); //此时打印的值为 'undefined'
var a = 1;
但若没有 var a; 则alert(a) 具有语法错误
javascript 中继承: 对象系统的集成特性有三种实现方式,1.基于类(class-based) 2.基于原型(prototype-based) 3.基于元类(metaclass-based), 在javascript引擎的基本实现中,对象(Object Instance)并没有原型,而是构造器(constructor)有原型,所以实例不能引用到其类的原型, 即instance.prototype 为定义,而且原型本身也是对象实例。其中关键字null是代表一个空对象的对象 但却不是Object实例,null instanceof Object == false; javascript中对象的构造过程可以被简单的映射为“复制”,当然包括从原型的复制,而且是写时复制。
prototype实例的由来:
var __proto__ = null;
function get_prototype(){
if (!__proto__){
__proto__ = new Object(); // 当prototype被获取时,被初始化为一个Object类的实例
__proto__.constructor = this;//将其constructor属性设置为当前的function
}
return __proto__;
}
javascript原型系统预定义属性与方法:
对象原型所具有的基本性质
成员名
|
类型 |
toString
|
function
|
toLocaleString
|
function
|
valueOf
|
function
|
constructor
|
function
|
propertyIsEnumerable
|
function
|
hasOwnProperty
|
function
|
isPrototypeof
|
fucntion
|
构造器Object()具有的特殊成员
成员名
|
类型
|
call
|
function
|
apply
|
function
|
caller
|
function
|
arguments
|
object
|
length
|
number
|
prototype
|
object
|
javascript 实例对象可以通过 .constructor 找到其构造器
function f(){}; var a = new f(); a.constructor == f, 但是原型继承是有弊端的,例如
function Base(){}
function Derive(){}
Derive.prototype = new Base();//这里原来的prototype的constructor被覆盖
//Derive.prototype.constructor = Derive ;解决方案之一;但这仍有问题,因为切断了原型链的性质
/*
解决方案二:但是效率欠佳
function Derive()
{
this.constructor = arguments.callee;
//this.constructor = Derive
}
*/
var b = new Base()
var d = new Derive();
b.constructor == d.constructor == Base()
//d.constructor沿着prototype链寻找constructor属性
javascript中的原型继承与类抄写:
function A(n){this.name=n;this.f=function(){alert(this.name);}}
function B(){A.call(this.'B');}
var b = new B(), b2 = new B();
b.f() // alert('B');
b instanceof A == false
b.f != b2.f
可见,类抄写是以空间换取了时间,但继承链的维护成员程序员的责任
javascript中的内置对象与原生对象:
内置对象与原生对象的区别在于,前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集,而后者还包括了一些在运行过程中动态创建的对象。如Arguments总是在引擎在函数调用时动态创建并添加在函数闭包中的。 javascript中的内置对象有11个:
对象
|
特殊效果
|
备注
|
Number, Boolean, String
|
值类型的包装类
|
值类型与它的包装类之间的关系是在引擎内部设定好的,没有办法替代,继承类不行 注: String.prototype.f=function(){return 'ok'} alert('00'.f()); '00' instanceof String == false
|
Array
|
自动维护的length属性
|
引擎隐式地维护,但继承类不行
|
Date
|
日期对象的相关运算
|
日期对象的方法仅能作用在有Date()构造器产生的对象实例上,继承的不行
|
Function, RegExp
|
可执行
|
其可执行特性无法继承 eg: function F(){} F.prototype=new Fucntion(); var myF = new F(); myF instanceof Function == true; 但是: myF() // 非法,myF不可以执行
|
Error, Object
|
|
|
Math
|
是一个实例而非类
|
在程序中直接引用
|
Global
|
程序中无法引用,引擎内使用
|
Global== window,程序中的window
|
posted @
2009-10-11 16:02 RUI 阅读(286) |
评论 (0) |
编辑 收藏
条件注释分为两种形式
一、IE普通的条件注释,如:
<!–[if lte IE 6]>[内容]<![endif]–>
这种形式的条件注释在非IE浏览器解析成普通注释,包裹的内容非IE浏览器不执行。
二、非标准注释的条件注释,如:
<![if gte IE 6]>[内容]<![endif]>
这种形式的条件注释包裹的内容却能被IE6+和火狐等现代浏览器执行,而IE也能对其执行条件判断。
但是这个却并非标准的HTML注释,不能通过W3C校验。
[b]关于条件判断释义:[/b]
if lte:低于或等于
if:如果
if !:如果不是
if lt:如果低于
if gte:高于或等于
条件注释是HTML注释的形式存在,所以只能写在HTML文档里面而不能写在CSS或者JavaScript里面!
posted @
2009-10-09 12:01 RUI 阅读(318) |
评论 (0) |
编辑 收藏
- Being good at looking around, It's reflected in the ways they organize the paper in their lives: books, reports, addresses, and so on. (software documentation)
- Being able to learn, within a single project's time frame, the people learn new technology, new problem domain, new process, and how to work with new colleagues.
- Being malleable, people are remarkably able to act differently given new motives and new information.
- Taking pride in work, people who have pride in their work do a better job than those who do not, and they are also more likely to step ourside of their own job descriptions to repair or report some other problem that they notice. the spontaneous behavior is key to success!
- Taking pride in contributing
- Being good citizens
- Taking initiative
In well run projects, people in any job description can notice when something is out of kilter and act to correct it or notify someone who can. this is an indicator of a community in action, not an indicator of a poor development process.
posted @
2009-10-06 21:49 RUI 阅读(209) |
评论 (0) |
编辑 收藏
Should programmer reward a.Lines of code sent to the test department? b.low defect rates delivered to the test department? c.function points delivered each month? d.the number of lines reused from a corporate libary? Now, we should think of what does the programmer actually reward?
1.Pride-in-work, one comments:'well, the system's ok.... I mean it functions, but I can't really take any pride in my work. I'd like to go home feeling good about my program, but I don't. It's just a big mess that barely works.'
2.Pride-in-Accomplishment, Using the principle of small wins as a motivating reward, a team delivers as early as possible the smallest thing that will count as a win for the team. 'simplest first, worst second' let team leans how to work together and gains an early win.
3.Pride-in-contribution, people's desire to contribute is so strong that they could damage their health and private lives in their effort to contribute to the team.
posted @
2009-10-06 21:09 RUI 阅读(175) |
评论 (0) |
编辑 收藏
Software development as both a thinking-intensive and communication-intensive activity presents an interesting dichotomy. Programmers need sufficient quiet time to get into a quiet and productive mode known as flow. After spending 20 minutes getting into a state of flow, it takes only a minute or two of other conversation to disrupt it.
posted @
2009-10-06 20:30 RUI 阅读(161) |
评论 (0) |
编辑 收藏
产生 **.tlb, **_i.c, **.h 命令如下:
MIDL YourName.IDL /tlb YourName.tlb /h YourName.h /iid YourName_i.c /Oicf
= = = = =
The /iid switch specifies the name of the interface identifier file for a COM interface, overriding the default name obtained by adding _i.c to the IDL file name.
midl /iid filename
=============
The /h option is functionally equivalent to the /header option.The /h switch specifies filename as the name for a header file that contains all the definitions contained in the IDL file, without the IDL syntax. This file can be used as a C or C++ header file.
midl /h tlibhead.h filename.idl
=============
The /proxy switch specifies the name of the interface proxy file for a COM interface.
midl /proxy proxy_file_name
zz:http://blog.csdn.net/sunshine1314/archive/2007/04/12/1562376.aspx
posted @
2009-10-06 19:45 RUI 阅读(789) |
评论 (0) |
编辑 收藏
The following failure modes should always be taken into account when run a project!!
1. people making mistakes:
People make mistakes is no surprise to us, however, iterative and incremental development were invented. Incremental development lets the team learn about its own development process as well as about the system being designed. During the process, the team members examine their working conventions to find out what should be improved, including team structure, the techniques, or the deliverables.It also allows people discovered the inevitable mistakes and repaired in a tidy manner.
2.people prefer to fail conservatively rather than risk succeeding differrently:
People intended to use the normal conservative strategy, a 'guaranteed' stdandard ourcome, rather than one that might work but might blow up in strange ways.
3.people prefer to inventing rather than researching:
In our earliest school days, we are instructed not to copy other people's work, not to help each other, and to be as original as possible in all but rote memory acts.However, we should be a good 'component assemblers' and accept a less glamorous design happily if it can be put into use quickly! we are in the serious competition!!
4. Being inconsistent creatures of habit:
We are creatures of habit who resist learning new behaviors, and at the same time we tend toward inconsistency!
5. Countering with discipline and tolerance:
"PSP is extremely rigorous, and if no one is asking for my data, it's easier to do it the old way" one trainee of PSP said! yeach, the alternative to requiring discipline is being tolerant of individual variation. The good methodology calls for the team members to form consensus on the minimum compliance needed in the work products and pratices. Each suggests the use of standards but does not require that standards be enforced!! Keep in mind: strict adherence to ineffective practices leads to an ineffective team.
posted @
2009-10-06 19:34 RUI 阅读(242) |
评论 (0) |
编辑 收藏
1.Software development should be considered as a cooperative game of invention and communication as well as Business executives, lawers, journalists, etc!
2. Consider running the project as two separate subprojects:
the first subproject produces the running software in as economic a fashion as possible.(project devlivery)
the second subproject , competin for key resources with the first, produces the final work products for the next team (maintain)
Good project management should follow the rules of :
a. Adding discipline on your project at key places.
b. Reducing discipline at key paces.
c. Declaring, 'Enough! this is sufficient!'
Key point:
a.Project Management
b.'Requirement' elicitation
c.User Interface design
d.System architecture
e.Program design and programming
f.Database design
g.Algorithm design
h.Testing
i.Commuicating!!!!!
posted @
2009-09-26 22:16 RUI 阅读(225) |
评论 (0) |
编辑 收藏