haoxiaobo

从C到C++又到.net, 有一些心得, 和大家交流下...
posts - 49, comments - 531, trackbacks - 1, articles - 6
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2012年2月6日

   网上这几天正在疯传一段用C#进行中文编程的段子,说一个程序员就职后,发现公司的大哥里把C#用中文进行了包装,不光是类,还有关键字也进行了中文化,正在苦恼是不是要继续在这个公司干下去。

   这位大哥这种精神是否可嘉还真不好评价。对于没有意义的事情执着追求,是可嘉呢还是不可嘉,估计还是要看评论的人是谁。不过,人家自己的执着,别人也确实无资格评价。

   还有所谓“意义”,恐怕也是因人而定义的。一个东西,对于为之付出了精力的人来说是有意义的,而对于其他人来说,即然与之没有交集,也就无资格置评。对于文中的小哥来说,喜欢的就留下搞搞明白,不喜欢的就走人吧。

 

    只是这段中文化的代码,很有意思,上午试着用C#的lamda实现了一下,就所看到的代码而言,基本算是都实现了,现在我也可以用中文编程了。

  

下面是中文编程的示例,基本与网上那个段子差不多。 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 中文编程
{
    class Program
    {
        static void Main(string[] args)
        {
            // 逻辑判断演示....
            判断.如果是(判断.真).则(() =>
            {
                Console.WriteLine("");
            }).否则(() => 
            {
                Console.WriteLine("");
            });
            // 遍历器演示.....
            登陆信息[] 所有登录信息 = new 登陆信息[100];
            // ....

            遍历器.计数遍历().从(0).到(99).每隔(1).执行((当前索引行) =>
            {
                所有登录信息[当前索引行] = new 登陆信息() { 姓名 = "姓名 " + 当前索引行.ToString() };
            });

            遍历器.枚举遍历<登陆信息>(所有登录信息).从(0).到(99).每隔(3).执行((当前索引行, 登录信息项) =>
            {
                Console.WriteLine(登录信息项);
            });

            数据库连接类 数据连接对象 = null;
            //异常处理........
            异常.对下列语句进行异常检测(() =>
            {
                数据连接对象 = 数据库连接类.连接到("10.1.138.35").用户名为("xxx").密码为("xxx");
                数据连接对象.打开连接();
               
                //... 
                throw new Exception("测试异常");


            })
            .发现异常则((异常对象) =>
            {
                //... 
                Console.WriteLine(异常对象);
            })
            .最终执行(() => {
                // ...
                数据连接对象.关闭连接();

            });
        }
    }

    public class 登陆信息
    {
        public string 姓名;
        public override string ToString()
        {
            return "姓名" + 姓名;
        }
    }
}

 

关键字的包装:-----------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 中文编程
{
    public class 判断
    {
        public const bool 真 = true;
        public const bool 假 = false;

        bool _b;

        public static 判断 如果是(bool 条件)
        {
            return new 判断(){_b = 条件};
        }

        public 判断 则(Action act)
        {
            if (_b)
            {
                act();
            }
            return this;
        }

        public 判断 否则(Action act)
        {
            if (!_b)
            {
                act();
            }
            return this;
        }
    }

    public class 遍历器
    {
        public static 枚举遍历器<T> 枚举遍历<T>(IEnumerable<T> 枚举集合)
        {
            return new 枚举遍历器<T>(枚举集合);
        }

        public static 计数遍历器 计数遍历()
        {
            return new 计数遍历器() { };
        }
    }

    public class 枚举遍历器<T>
    {
        protected IEnumerable<T> _set;
        protected int _iStartIndex;
        protected int _iEndIndex;
        protected int _Step;

        public 枚举遍历器(IEnumerable<T> 枚举集合)
        {
            this._set = 枚举集合;
        }

        public 枚举遍历器<T> 从(int 开始元素序号)
        {
            this._iStartIndex = 开始元素序号;
            return this;
        }

        public 枚举遍历器<T> 到(int 结束元素序号)
        {
            this._iEndIndex = 结束元素序号;
            return this;
        }

        public 枚举遍历器<T> 每隔(int 每隔步长)
        {
            this._Step = 每隔步长;
            return this;
        }

        public void 执行(Action<int, T> 循环体方法)
        {
            int i = 0;
            foreach (var e in _set)
            {
                if (i >= this._iStartIndex && i <= this._iEndIndex)
                {
                    if ((i - this._iStartIndex) % this._Step == 0)
                    {
                        循环体方法(i, e);
                    }
                }
                i++;

            }
        }
    }

    
    public class 计数遍历器
    {
        protected int _iStartIndex;
        protected int _iEndIndex;
        protected int _Step;
    
        public 计数遍历器 从(int 开始元素序号)
        {
            this._iStartIndex = 开始元素序号;
            return this;
        }

        public 计数遍历器 到(int 结束元素序号)
        {
            this._iEndIndex = 结束元素序号;
            return this;
        }

        public 计数遍历器 每隔(int 每隔步长)
        {
            this._Step = 每隔步长;
            return this;
        }

        public void 执行(Action<int> 循环体方法)
        {
            for (int i = this._iStartIndex; i <= this._iEndIndex; i += this._Step)
            {
                循环体方法(i);
            }
        }
    }

    public class 异常
    {
        Exception _ex = null;

        public static 异常 对下列语句进行异常检测(Action 正常执行程序)
        {
            try
            {
                正常执行程序();
                return new 异常() { _ex = null};
            }
            catch (Exception ex)
            {
                return new 异常() { _ex = ex};
            }
            
        }

        public 异常 发现异常则(Action<Exception> 异常处理程序)
        {
            if (this._ex != null)
            {
                异常处理程序(this._ex);
            }
            return this;
        }

        public 异常 最终执行(Action 最终处理程序)
        {
            最终处理程序();
            return this;
        }
    }
}

 

数据库连接的包装: 

 

using System;

 

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace 中文编程
{
    public class 数据库连接类
    {
        private string _sServer;
        private string _sUID;
        private string _sPassword;
        private string _sDBName;
        SqlConnection _sqlconn = null;

        public static 数据库连接类 连接到(string 服务器名)
        {
            return new 数据库连接类() { _sServer = 服务器名 };
        }

        public 数据库连接类 用户名为(string 用户名)
        {
            _sUID = 用户名;
            return this;
        }

        public 数据库连接类 密码为(string 密码)
        {
            _sPassword = 密码;
            return this;
        }

        public 数据库连接类 数据库为(string 数据库名)
        {
            _sDBName = 数据库名;
            return this;
        }

        public void 打开连接()
        {
            this._sqlconn = new SqlConnection(string.Format("Data Source={0};Initial Catalog={1};User ID={2};Password={3}"this._sServer, this._sDBName, this._sUID, this._sPassword));
            this._sqlconn.Open();
        }

        public void 关闭连接()
        {
            this._sqlconn.Close();
        }

    }
}

 

说实话,感觉很奇怪。

 

posted @ 2012-02-06 15:03 HAL9000 阅读(4016) 评论(73) 编辑

2012年1月9日

这是这几天里我同时解决的另一个问题。

我用的是VC2003,在非托菅的本机代码中调用webservice时,很有一些令人糊涂的地方,在这里记下来,以后也方便自己回忆。

 方法:

1.增加webservice引用。

2.自动生成代理类。

上面简单。但当看着所生成的代理类时,多年没碰过VC代码的我哭了……VC的代理类是下面这样的:

 template <typename TClient = CSoapSocketClientT<> >

class CWebService1T : 
public TClient, 
public CSoapRootHandler
{
。。。

}

模板套模板。。。

嘛意思?

意思是:代理类在实例化时,要指定一个网络客户端工具类。默认这个类是CSoapSocketClientT<>, 这也是一个模板类。

template <typename TSocketClass = ZEvtSyncSocket>
class CSoapSocketClientT

{ 。。。}

看,默认的默认类是ZEvtSyncSocket,这是个啥类我实在没有心情去研究,看名字是一个Sock通讯类。不要不要!

那么调用webservice方法仲么办? 要这样:

 

 CWebService1T<CSoapWininetClient> proxy = new CWebService1T<CSoapWininetClient>;

proxy->SetUrl("http://xxx.com/Webservice1.asmx");  

proxy->HelloWork();

 

这里我没有用VC神经乎乎地推荐的那个 CSoapSocketClientT<ZEvtSyncSocket>, 而是用了CSoapWininetClient类做为工具类(atlsoap.h)。

注意上面的代码,有一个SetUrl的方法调用,这个方法你一定在代理类中找不到,但是编译运行又都正常。奇怪不? 

 请您这时候再回去注意一下CWebService1T的定义,CSoapWininetClient被置换为TClient泛型参数,而TClient又被放在了类定义的冒号后面,啥意思?

就是说你代入的这个模板参数类型将是代理类的父类呀!简直把人绕晕了!

 也就是说,我写CWebService1T<CSoapWininetClient> proxy 时,CSoapWininetClient将是CWebService1T<>的基类!CSoapWininetClient有SetUrl, SetProxy等方法,所以proxy 也就可以调用这些方法了。

因为 CSoapWininetClient是用了Wininet.dll库的api进行通信的,这个库的特点就是支持http,而且和ie的设置是相通的,因此,用了这个工具类,你的proxy对象就可以透过代理服务器调用webserivce了。

 

一切问题都解决了?没有。

 

我这两天遇上了几个做难死人的问题——一个客户的网络需要用代理服务器上网,而且是需要输入口令的。

本来这个问题也不是问题,只要ie能上网,在代理服务器要口令时,输入口令并选一下保存密码的复选框,这个用户凭据就会记录在系统中, CSoapWininetClient就可以自动取用,  很多客户的网络环境都是这样的,我们的客户端程序运行得很好。

但是不幸的是,这个客户的机器被设置了策略,就算是在ie里选了保存密码的复选框,密码也不能保存下来,每次打开ie时,都需要重新输入口令。

既然系统里没有用户凭据,CSoapWininetClient也就没有办法从ie得到用户名与口令。

 

我研究了CSoapWininetClient这个类,可恨的是这个类没有任何事件、callback、委托等扩展渠道让我在合适地地方切进去,设置那些代理啦、用户名啦口令啦什么的。在代理类调用hellowork时,就调用CSoapWininetClient的第一个方法就是SendRequest方法,在这个方法里,它打开对话,建立连接,Post数据、得到回应的流,一气呵成了!中间没有用户的机会加入代码。

 

我发愁了老半天,决定从 CSoapWininetClient派生一个子类来用,想试试能不能通过重载一下某些方法来介入自己的代码。这叫什么模式来着?装饰类?

 

结果发现这个类里很多粉重要的方法、成员都是private的,没法引用。

 

真没有办法了?我暴怒了!我和他拼了!我把 CSoapWininetClient类的源代码全拷贝出来,在项目里建了一个新类,叫CFuckedSoapWininetClient, 然后把CSoapWininetClient类的所有内容都复制了进去,现在,你是我的啦!哇哈哈!

 

再把调用Webservice的代码改一下,把参数类名改为Fuck过的新类。

 CWebService1T<CFuckedSoapWininetClient> proxy = new CWebService1T<CFuckedSoapWininetClient>;

proxy->SetUrl("http://xxx.com/Webservice1.asmx");  

proxy->HelloWork(); 

编译,通过。运行,通过!


现在,通信类是我的了,任我哪啥了!想加代理服务器支持,那是易如翻掌了。

 

有关 代理服务器支持 功能的实现,请参考另一篇文章 http://www.cnblogs.com/haoxiaobo/archive/2012/01/09/2317559.html

 

posted @ 2012-01-09 22:49 HAL9000 阅读(152) 评论(0) 编辑

摘要: 好吧,我遇上了windows api的bug... 并贡献一个完全支持代理服务器的http文件下载VC代码阅读全文

posted @ 2012-01-09 22:04 HAL9000 阅读(279) 评论(0) 编辑

2012年1月7日

域账号多次被锁,看起来是有人在狂试我的账号似的,解决办法记录一下。

 

 在ad控制器里,安全日志里做如下查找:

 

事件id:644

意思是Lockout事件。

内容:输入要搜索的账户名。不必输入域名。

 

查到到日志之后,看看内容里的来源工作站名。

 

去那个工作站上,查查有没有用此账户运行的定时任务、服务啥的。如果从前有,后来你改了口令,这些任务就不能运行了,可能会一遍遍用旧口令启动,最后达到次数上限锁定你的账号。

 

如果没有明显的此类任务,查查是不是有一种叫Downadup的病毒。这个病毒会利用rdp的一个安全漏洞感染机器,如果你改了用户口令,这个病毒会重试你的账号直到lockout.

从symantec网站上可以找到专杀工具。

http://www.symantec.com/content/en/us/global/removal_tool/threat_writeups/D.exe

  

杀完病毒之后,可以按工具的提示去查看ms08-67安全公告,并下载补丁KB958644修复漏洞。

这个漏洞到从windows 2000 到 windows7 beta版和windows 2008 server为止都存在。在windows7 和windows 2008 Server r2开始不存在了。

 http://technet.microsoft.com/zh-CN/security/bulletin/ms08-067

要检查系统中有没有已经安装对应的补丁,可以检查KB958644是否安装。 

posted @ 2012-01-07 15:06 HAL9000 阅读(17) 评论(0) 编辑

摘要: 如何在CInternetSession下传文件时,设置要求用户名口令的代理服务器? 如果安装了ie8,CInternetSession会自动采用ie的设置和用户保存的凭据,程序是完全透明的,但ie6下,相同的程序行为不同了,如何显式地设置代理服务器与用户名口令呢?请高手赐教!!!阅读全文

posted @ 2012-01-07 14:45 HAL9000 阅读(628) 评论(0) 编辑

2011年8月31日

    
    既然已经上线了这样的“标准流程”的核心业务系统,就必然会立即遇上各种地域化问题。前面说过,中国各地发展极不同步,在经济、文化、政治、民间风俗、人文道德水平方面全国各地千差万别,相同的业务要求不同的服务方式是不可避免的。
    比如说我们上线不久遇上的一个事情:这些年政府管控的力度越来越大,不仅管产品,管财务,还要管到各个公司的内部操作流程上,搞得大家都很难受,不知道国家是不是想要回到计划经济的路子上去。就是在这种背景下,我们分公司所在的当地政府的一些监管机关经常搞出个通知,要求在某个业务办理时,所出具的业务材料必须按官方规定的文字向客户进行书面表述什么的。
    新业务系统上线之后,这种小小的需求也必须要向总公司提申请要求修改了。业务系统本来对于操作中的打印件采用了模板技术,如果需要修改内容,只需要修改模板中就可以了,但是问题是这个修改是只对我们一个分公司的,其他分公司没有这样的要求(或是其他的什么要求,都不一样),一但这个模板修改了,全公司都会跟着我们的样式生成打印件。
    这个需求提到总部IT之后,负责的家伙着实地发了一阵子愁,最后还是没有好办法,只好在崭新的系统代码里加上了那个肮脏的“if(strncmp(deptno, “BEJ”, 3) == 0)…”,在我们公司的操作员在操作这种业务时,特别地调用一个专门的模板文件。
    在目前的社会环境下,这种需求一定会很多,不仅有这样特别打印件的问题,还可以设想其他可能存在的同样地域性需要:
    l 在UI上某处为某个地域的操作增加某些特别提醒信息
    l 必要时还要跳出个MessageBox\alter来。
    l 打印外文版文档。
    l 某地区在标准流程中特别插入的步骤。
    l 某地区对某个业务的前置\后置检查逻辑。
    l 某种特别需要的警戒线提示。
    l 特别的数据展示格式。
    l … …
    对于这些域化的需求的解决方案,我在操作系统的设计中得到了启发。
     
    a)        地域化静态资源扩展
    操作系统常常需要开发不同的语言版本,为了简化开发,一般会将UI中所用到的字符串、图片、多媒体文件等做为一种“资源”来单独处理。操作系统中总是有一套Default的资源文件,然后为不同的文化和语言分别准备不同的特定资源。如果当前的文化设定所对应的特殊资源没有提供,那么系统就采用默认的资源,比如英文,如果存在当前文化设定对应的特殊资源,那么就采用特殊的资源。
    这个思想完全可以借签到业务系统的设计中,把分支机构如同操作系统中的一个文化-语言来处理,对于系统中所需要的资源类内容,按分支机构整理。在默认的情况下,系统会加载default资源来处理,而当一个分公司有特别需要时,为其特别定义一个资源,这样系统优先使用这个特殊定义的资源,使得系统可以方便地按地域提供个性的服务。
    应该说我们的系统还是考虑到了一个层面,就是可变的模板让标准内容可以方便地修改,可惜没有进一步认识到各地区差异需求必然性,现在,该为业务系统的设计者提个醒了——当你设计一个要用到全国各地的系统时,地域化支持就成了必然要考虑的问题。
     
    b)        应该考虑客户化插件标准
    还有很多地方对于功能类的扩展要求,也可以参考操作系统的“事件”思想。就是说核心业务系统可以按标准的操作过程执行,但是同时设计一种机制,可以在某些时机来callback触发预定的“额外功能插件”。
    所述的“时机”可能如下的情况:
    l 一个订单生成之前、之后。
    l 操作员登录后、注销前。
    l 某些信息安全事件。
    l ……
    对于这些事件,系统应该有一种标准化的“定阅”协议,使得程序员可以方便地注册定阅程序,这样在事件发生之后,系统根据定阅记录触发注册程序。这些程序可能不只一个,而且可能只是对与某个分支机构有关的事件才会触发。
    这里需要注意的系统的健壮性如何不受callback程序的影响,比如从技术上限定callback程序可以做的事情或不能做的事情,甚至要求callback程序只能是异步执行等。
    进一步地,可以将一些常见的插入任务制式化,比如特别的消息提示,电子邮件通知,存档,简单的表达式计算与数据检查,这些常见任务可以固定为可选用的任务模板,通过预定参数来达到不同的目的。
     
    应该承认,在整个系统中的所有的可能的地方实现这些可定制、可插入,其成本必然是很高的,但是,应该在系统中为这些特性做好技术的准备,你应该把加载资源的函数增加个分支机构代码参数,以备在需要时可供使用。也应该规定好事件触发的技术协议,那怕是通过某个规定的数据表中的记录来传递消息,只要有标准就行。
    如果你在系统设计中没有增加这些特性,那么你在发现自己在第二次在同一个地方写入“if(strncmp())…”时,总应该开始认识考虑这个问题了吧?一个if可能是个偶然的个性问题,两个if出现在同一个地方时,你应该能认识到这是一个值得重构的弹性需求点,及时在这个地方引入地域资源化、事件订阅等设计模式,以免在上线第二个月时,就把你崭新的系统代码挂上一串串的大便。
    

posted @ 2011-08-31 21:34 HAL9000 阅读(1123) 评论(1) 编辑


商业公司的业务同质化很高,市场如战场,谁能快一步应变,谁能给客户提供个性化,谁就得到了业务,谁就能生存。特别是象中国这样各地的经济、文化、政治极其不平均的国家,中央与地方的差异鸿沟巨大,地方特色必然需要。

但是站在总公司的管理角度上来考虑,当然是希望业务流程越规范越好,新花样总是意味着管理上的潜在危险。而对于总部信息技术部门的角度来看,个性化的新花样则是开发工作量的剧增、无止无尽的新需求。

管理与市场、领导与客户、全局与局部、总公司与分公司之间,这个思路方向性的矛盾是现实存在,而且不可避免的。

当然,最后项目还是要按上级的管理意图来实施,于是我们得到了一个全国一致的系统,一个唯一可用的UI,一本统一印发的操作手册。对于常规的业务,按着系统的要求操作就可以满足需要了。但是这个系统不再给机会进行业务、技术的创新,一切新的想法只能做为新需求向上级提出,然后由情绪恶劣的IT人员在程序里加入一个个 “if(strncmp(deptno, “BEJ”, 3) == 0)…” 这样丑陋到暴的代码来完成流程定制化。

 

其实要在同一个系统里同时满足总分公司双方的诉求,并不是不可能,就是把应用系统分为两层:业务逻辑与UI层,业务逻辑层是对业务逻辑的原子化,以实时服务的形式提供。在此业务逻辑服务的基础上,构建界面展现。

这里的关键点在于业务逻辑服务的提供,不仅可以是标准UI对其的进程内调用,也同时需要能够通过webserivce等协议提供进程外服务。对于标准流程,可以由总部来做“典型实现”,而对于有特别需要的分部,则可以方便在业务服务的基础构建业务系统的其他前端外延。

这样,从管理的角度上来讲,业务数据的进出都是通过标准服务来进行的,业务数据质量、业务一致性、合规性都可以通过统一的业务逻辑来得到保证,而分支机构则有机会为不同的业务开发不同的前端接口,以根据市场要求灵活创新。

这种模式特别适合于有外部合作机构的公司采用,如金融企业、电子商务企业等。如果业务系统只有一个UIIO方式,一切数据进出都要通过操作员来进行,那么与其他合作方进行自动化的数据对接就很难实现,一但有这样的需求,只能由交由掌握了底层逻辑的总公司IT从头开发。

现在我们的系统已经上线,可惜的是,系统采用了最简单最直觉的思路开发,几乎要把业务逻辑写在界面里了。事已至此,也不可能有什么改变了,这里只是我有过的想法分享出来,作为讨论。

posted @ 2011-08-31 20:21 HAL9000 阅读(1304) 评论(1) 编辑

摘要: 近一段时间,公司上线了一个全国性的业务系统,这个系统功能覆盖了全部业务流程,用户包括全国32个分公司,可谓是一个把所有鸡蛋放在同一个蓝子里的巨大系统,上线过程多么辛苦不说了,只说上线后的一些问题所带给我的一些关于业务系统设计启发。阅读全文

posted @ 2011-08-31 14:15 HAL9000 阅读(1518) 评论(13) 编辑

2011年2月14日

    有位老兄写了一篇《被高估的几种it技术》,大部分都没意见,只是对于其中xml, oop, 云计算、web service,敏捷开发几项,感觉应该客观地再评价一下。
     
    
    xml 
    
    
    xml有其他数据语义标准之长,而无之短,只是语法上上有点儿冗余,但是这东西主要还是让计算机看的,捎待让人看懂已经很不错了。如果你玩过银行里那种古系统中的文本文件数据报文你就知道xml的好了。xml还有一整套配套的技术,如xmldoc, xpath等辅助使用。
    我见过用字符串拼接、查找来生成xml或是解析xml的(好可怜的程序员),这种用法是在用xml的皮毛,如果你是这样的程序员之一,那快去系统学习一下吧!不然要累毙了。 
     
    
    
    oop 
    
    原作者认为oop的设计模式把程序开发搞复杂志了,实际上oop与设计模式不是一回事,oop的思想根本上是把现实世界在计算机中建立映射,这是很好很有效的降低开发复杂度的办法。设计模式是是在oop基础上的算法总结,是指导而非要求。要反对的是学院派由于《设计模式》一书的存在而“过度设计”,而非是oop本身。但是,当你系统扩展弹性要求高了之后,你会发现答案还是设计模式中的一些办法。
    我没有看过《设计模式》之前,多年做oop的开发,之间为了解决问题而想出了不少设计办法。后来为了不被学院派精神虐待而看了《设计模式》这本当年的“圣经”之后,发现其中大半的设计办法我早就在之前的工作中自行发明使用过了。
    
     
    
    web service 
    
    web service是目前最好的解决平台间数据通讯的技术了。中立的数据类型,支持对象的语法规则,中立的通讯协议,自动代理方法工具,甚至连异常都能跨平台传输,你还需要啥呢?
    不过,它的确不是万用法宝,它只能解决他适合解决的问题。ibm最会炒概念,你迷信ibm是你无知, webservice仍然工作得让人安心。
    最后,要是如果能解决web service的接口版本的兼容性问题就更好了,不解释了,用过的就知道我的意思。
    
     
    
    敏捷开发 
    
    敏捷开发的一个潜台词是“高手开发”,“敏捷” 的核心就是:深刻理解业务需求 + 合适(成本、可扩展性的均衡)地实现需求+ 一有必要立即重构以增加设计弹性 + tdd(质量保证)。所有这一切都需要高手才能做到。关于双人编程,实践中发有两个巨大好处: 一、知识传承没有问题了。二、两个人一起工作,注意能高度集中几倍于单人工作时的时间,三,讨论能理清思路。
    “敏捷”中文档的问题:同步程序与文档是一件很麻烦而没有效果的事情,后来人一般不会看详细设计的文档,更别提你的文笔也不一定达到让人能轻松读下去的水平。我的解决办法是:
    
    一:设计文档就到架构设计。说明程序结构、设计思路、数据库设计,聪明人看过之后就明白你的意思了,一般不需要更详细的文档了。 
    一:程序就是文档,我不在乎你的变量名有多长:匈牙利命名法 、动词短语方法名。后来人看你的程序要像看一篇文章那么清楚。
    二:文档注释,必要的过程\算法\注释对接口方法进行说明。然后ndoc之类的工具就可以生成文档了,比自己搞得好得多,而且不会出错。
    
    对于大型的系统,我的实践经验是:在架构设计层面(系统设计、程序结构设计、数据库设计等),高手进行“敏捷式设计”,而具体的实现可由普通开发人员完成,一则提供优秀的系统设计、为未来始终留下扩展余地,二来也不会过度设计导致实现成本过高,三来普通的开发人员的工作也好干。
    
    题外话:与高手一起工作的惬意无与伦比。
      
    
    
    云计算
    
    其实这是一个基础运行体系的解决方案,在专业it运行领域,虚拟化、基于冗余思想的高可用硬件是多年以来企业级厂商努力的方向。
    虚拟化有两个方向,一个是把一个高性能的硬件分为多个虚拟机运行,如ibm的高端机型,另一个方向是把多个物理机整合为一个虚拟的单一机器,任务分散、分布执行,从而得到高性能计算能力。
    云的意思是两者的结合——多个物理机整合为一个虚拟机,这个一个虚拟机上再分为多个独立的逻辑单位,用于隔离不同的应用程序运行空间。这样,即得到了应用程序管理的便利,又得到了冗余硬件的可靠性,以及高弹性的性能管理。只要你做过基础运维你就会理解这个东西的宝贵。
    
    一个IT经理高声呼喊,快点到来吧,云计算!我需要一个私有云来解放我!

posted @ 2011-02-14 15:31 HAL9000 阅读(226) 评论(0) 编辑

2010年12月31日

摘要: 0 概述 Tuxedo是类似于Message query server的一种东西,它以消息服务器的方式提供一个服务器框架,客户端向服务器发送请求报文,服务器处理之后返回应答报文。当然,服务器有对消息队列的各种管理能力。 我猜这个东西最初提供给客户的动机是为了保留客户用C开发的业务逻辑,又能方便地把自己的系统改造为面向服务的交易系统, 毕竟客户们的系统已经正常运行多年,该卖给他们一些新东西了。 因为要与C兼容,还有客户们现存应用的多样性问题,Tuxedo决定在设计上不提供消息语法与语义的支持,只是透明地转发数据块——也就是说,C语言里的char*,struct*, 甚至是void*. 于是,很阅读全文

posted @ 2010-12-31 09:04 HAL9000 阅读(1952) 评论(3) 编辑

2010年12月21日

摘要: 从前的经验是:二进制文件的读写效率比文本的高,不要说还要解析xml结构啥的。于是,前几天需要暂存内存里百万条左右的数据时,毫不迟疑地选择了BinaryFormatter.每次重新读回内存都要N长时间。最后一次,为了方便人工查看,改了一下用了XmlSerializer来保存数据,人工查看处理完之后,再加载到内存里,突然感觉怎么这么快!于是找时间做了个测试,发现自己杯具了,知识更新太慢,不知道原来xml的效率已经超过bin了!下面是对比: XmlSerializer BinaryFormatter 读 59,031 ms 117,763 ms 写 61,925 ms 64,565 ms 文件容量 阅读全文

posted @ 2010-12-21 20:26 HAL9000 阅读(937) 评论(6) 编辑

2010年6月1日

摘要: 刚刚第三篇的发布时,cnblog告诉我一个小时里不能发两次精华。可是我写一千来字都花不了一个小时。今天思路比较快一些,呵呵。 最后,我再聊聊我新近观察的一个项目的运作,来分享一下我的第三层认识。 在达到了第二层关于政治风险的认识水平之后,我保持了这个认识水平有一段时间。当然我也无法左右公司高层的选择,反正有钱就花吧!只是有些系统自己要用的,难用成那样实在不爽,有时候也不免发发牢骚。 我有一个哥...阅读全文

posted @ 2010-06-01 15:13 HAL9000 阅读(5837) 评论(65) 编辑

摘要: 公平地讲,这个项目有很大的技术难度,开发的风险很大。一开始是个烫手项目,倒不是因为有政治方面的问题,高层都肯定是下了决心来做的,但大家都已经算计过了,这个项目的技术难度这么大,有50%的可能性是会做烂掉的,公司里没有多少人敢接手负责。但是这个项目又必须做,最后就指定一个项目负责人来强迫他来做这个项目。 其实这个项目虽然难,但都是技术方面的难度,最少50%可能性是会很成功的。于是负责人就会硬着头皮...阅读全文

posted @ 2010-06-01 14:04 HAL9000 阅读(4345) 评论(21) 编辑

摘要: 如前面所述的,由于很多人已经被洗过脑,还有其他很多操作上的考虑,大家都会很自觉地配合IBM的营销攻势,而且我们也衷心相信:在IBM等软件和硬件的支持下,我们的一个个系统步入了“高档系统”的行列。把.net平台留给了孩子们玩去吧。 其实,IBM,以及其他一些高端厂商(Oracle, BEA等)做承接的项目,大部分的活计是直接再转包给其他国内的小厂商的,他们自己所需要做的,基...阅读全文

posted @ 2010-06-01 13:32 HAL9000 阅读(5050) 评论(54) 编辑

摘要: 好久不在这里写文章了。先祝各位六一儿童节快乐! 我是一个从野路子上一路走来的程序员,现在主要用.net做方案。选.net不选jave并没有什么特别的原因,只不过是因为我自己从C开始学起,一直学到C#, 很熟悉这个平台罢了,从业15年了,C#是最方便的一个语言,而VS是最方便的一个工具,因此就很自然地用C#来解决我的一切问题,而这个工具也没有让我失望过,基本上还没有遇上过解决不了的问题。 但是在现...阅读全文

posted @ 2010-06-01 11:40 HAL9000 阅读(8039) 评论(68) 编辑

2009年4月8日

posted @ 2009-04-08 11:58 HAL9000 阅读(3344) 评论(13) 编辑

2008年7月18日

摘要: 只是一个简单的测试, 用了三种方法来做10万条记录的插入. 不过我没有测试拼10万条sql插入的效率.应用在:dell inspiron 640M本本上跑的. 1.60双核CPU, 2G内存. 服务器是HP360, 8CPU, 4G内存. SQL2000数据库.仅供参考.一.每次都调用ctx的InsertOnSubmit方法把对象放入:2008-7-18 14:29:55开始生成100000个对象...阅读全文

posted @ 2008-07-18 21:54 HAL9000 阅读(1818) 评论(27) 编辑

2008年7月17日

摘要: 多年了,没有什么技术再能让我激动得无法控制住自己,包括WPF的超炫界面功能,我也只是小小地喜悦了一下,但毕竟知道界面设计更多还是美工创意的功夫,见过很多品味不够的开发人员,把自己程序界面搞得花里胡骚,简直得像不小心坐在调色板上的大熊的屁股,只能让人笑话。所以WPF的UI能力似乎离自己还有距离。
  但是,Linq,却真得把我雷到了。在我重新坐下来写这段话之前,我是激动得在屋里转了几圈的,嘴里至少把MS骂了十来句“WC!”,这骂不是怀了恨意的骂,而是怀了敬意的骂,是没办法控制自己兴奋和激动的心情的骂,就像是《朱罗纪公园》里的马尔康姆教授第一眼看到人工DNA造出来的活恐龙时,说的那句话:“这帮狗娘养的真的做了!”
阅读全文

posted @ 2008-07-17 23:04 HAL9000 阅读(3547) 评论(73) 编辑

2005年11月14日

摘要: 在MSDN上闲逛,无意中看到一个这样的东西:屏幕逻辑集成.SLI(屏幕逻辑集成,Screen Logic Integration)用于将古老的UNIX绿色终端字符界面的程序包装成为一个web services, 以便在SOA的架构里重用这些古老的业务逻辑. 比如, 在我们公司中, 业务系统是基于UNIX的终端程序,一些业务逻辑是在界面上的一些输入框里输入参数, 一些资料, 或是计算结果被显示在屏幕...阅读全文

posted @ 2005-11-14 11:30 HAL9000 阅读(793) 评论(1) 编辑

2005年9月16日

摘要: 项目组的文档风格问题  叫我怎么说?我们项目组里现在充斥着华而不实的文档作风. 做一件事,这样浮燥,这样不脚踏实地是不行的.  写工作文档,规范严格是重要的,但并不是要把简单问题往复杂了搞,不是要把实际问题抽象化,不是要去找一些意义含糊的词语来表达,不是要把一句话可以说明白的意思用一大段话来说得人人都看不懂!  说到工作文档,我想有下面几点要做好,就够了.  一.句法不能出问题:主谓宾一个也不能少...阅读全文

posted @ 2005-09-16 11:49 HAL9000 阅读(766) 评论(14) 编辑