这篇文章写于今年6月间,当时正在为一个项目设计扩展性和插件功能,同时又刚刚读过Alexandrescu的《Modern C++ Design》,深陷于模式之中不能自拔。这篇文章曾经被放在了我在CSDN的专栏中。当时放上去的时候,自以为是地觉得文章写的不错,于是就推荐给了《程序员》杂志,杂志回信说被采用了,因此在CSDN文档中心,一直到现在这篇文章也不能浏览,只有几个朋友私下里看过。前两天又有朋友提起,想想它可能早已被《程序员》编辑们遗忘了吧,于是将它放在了这里:http://blog.joycode.com/sam1111/posts/10162.aspx 希望和更多的朋友交流。由于blog贴图的限制,文章中有一个类图没有贴上,不过那只是个简单的继承体系,并不影响对全文的理解
对象工厂
对象工厂(Object Factory)模式通常被用来从一个派生系统中产生某个对象,并将其作为基类的实例返回,从而获得基类的接口,并尽量掩盖派生类的细节,以便充分利用面向对象的多态性来获得强大的功能。通常,对象工厂的实现方法是,在一个工厂方法中,先利用一个基于类型标记(type tag)的switch语句找出适当的类型,然后创建该类型的实例并返回之。
举例来说,设想一个图形系统,它包括了线、圆、矩形等元素,这些元素具有一些公共的操作,比如Draw、Resize等。那么我们可能具有下面这样一个继承体系:

为了能够在对象工厂中区分这些类,我们还需要为它们分别指定一个类型标记。这些类型标记可以是Enumeration、整数、字符串等能够唯一地标记这些类的值。用它们的类名字符串作为标记看起来不错。我们可以使用下面这个对象工厂来创建Shape对象:
public sealed class ShapeFactory
{
private ShapeFactory()
{
}
public static BaseShape CreateShape(string shapeID)
{
switch(shapeID)
{
case "Rectangle":
return new Rectangle();
case "Circle":
return new Circle();
case "Line":
return new Line();
default:
return null;
}
}
}
ShapeFacory的唯一用途就是用来创建Shape实例,我们不希望它本身那能够被继承,或者能够被实例化,因此,它被声明为sealed,并具有一个私有构造函数。当我们需要得到某个Shape的实例时,只要调用ShapeFactory的CreateShape()方法,并传入一个适当的shapeID字符串,CreateShape()就会为我们返回正确的Shape实例了。
增强扩展性
现在我们拥有了一个Shape工厂,它工作的不错。但是这个工厂具有一个明显的不足:难以扩充。每当系统中新增加一个Shape类时,我们都不得不修改CreateShape()方法,向其中加入新的case语句。这在我们的产品没发布之前还好,我们可以完全控制我们的代码。但当我们的产品发布之后,用户可以很容易地从BaseShape派生自己的Shape类,但他们却很难利用CreateShape()方法将他们的Shape类加入到系统中,因为他们无法修改CreateShape()方法的实现。因此这个Shape工厂还需要一些扩展性。但是解决这个问题的一个主要的障碍是,如果不使用switch语句,那么CreateShape()将无法预先知道到底存在哪些Shape类,以及类型标记与具体的类之间的关系。
Alexandrescu在他的《Modern C++ Design》中针对这个问题给出了一个C++解法。他在对象工厂类中利用一个std::map来维护类型标记与类型的创建方法之间的关系,并在对象工厂类中增加了两个接口Register()和Unregister(),用来在此map中注册或注销类型标记和类型创建方法。每增加一个Shape类时,需要同时为这个类写一个匿名名字空间,在此空间中调用Register()方法,将自己的类型标记和创建方法注册到对象工厂中。
在C#中,我们可以借鉴Alexandrescu的方法,在对象工厂中利用一个Hashtable来维护类型标记与类型之间的关系,利用Register()方法来注册。每个Shape类必须负责自己的注册工作,因此我们为每个Shape类增加一个RegisterShape()方法,它调用ShapeFactory.Register()来注册自己。但是有两个问题:
1、 对RegisterShape()方法的调用应当何时进行呢?
2、 C#并不支持匿名名字空间,那么如何来调用每个Shape类的RegisterShape()方法呢?
对于第一个问题,我们有一个时机,那就是在CreateShape()方法被调用之前,各个Shape类必须已经完成了注册。在静态构造函数中完成对RegisterShape()的调用到是个不错的选择。
对于第二个问题,我们可以使用Reflection机制,首先遍历所有的类型,找出由BaseShape派生的类型,然后分别调用它们的RegisterShape()方法。
按照以上思路,ShapeFactory的实现代码如下:
public sealed class ShapeFactory
{
private static Hashtable _creationMap = null;
static ShapeFactory()
{
_creationMap = new Hashtable();
Assembly a = typeof(ShapeFactory).Module.Assembly;
Module[] modules = a.GetModules();
for(int i = 0; i < modules.Length; i++)
{
Type[] types = modules[i].GetTypes();
for(int j = 0; j < types.Length; j++)
{
if(!types[j].Equals(typeof(BaseShape))
&& types[j].BaseType != null
&& types[j].BaseType.Equals(typeof(BaseShape)))
{
Object obj = types[j].InvokeMember(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.CreateInstance,
null, null, null);
types[j].InvokeMember("RegisterShape",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod,
null, obj, null);
}
}
}
}
public static void Register(string shapeID, Type shape)
{
if(!_creationMap.ContainsKey(shapeID))
_creationMap.Add(shapeID, shape);
}
public static BaseShape CreateShape(string shapeID)
{
Type shape = (Type)_creationMap[shapeID];
if(shape == null)
return null;
return (BaseShape)shape.InvokeMember(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance | BindingFlags.CreateInstance,
null, null, null);
}
}
在CreateShape()方法第一次被调用之前,静态构造函数会先执行。它利用Reflection机制遍历所有的类型,对于由BaseShape派生的类型,先创建一个实例,然后调用其RegiserShape()方法,将其在Hashtable中注册。当CreateShape()方法被调用时,根据传入的shapeID从Hashtable中取出相应的类型,并返回其实例。这样,我们就有了一个具有一定扩展性的Shape工厂。
总结
在对象工厂中增加Reflection机制,可以在一定程度上增强对象工厂的扩展性。改进后的ShapeFactory不用再在每次增加了Shape类之后进行修改了,只要新加入的Shape类实现了RegiserShape()方法,它就能够被注册到对象工厂中,并被正确地创建。这样,我们甚至可以方便地为我们的系统实现插件功能。比如,我们可以指定一个插件目录,遍历这个目录,将其中的Shape类注册到工厂中。用户只需将他们的插件拷贝到这个目录下即可。
当然,Reflection也许并不是此问题的最佳解决方案。它需要遍历系统中所有的类型,执行效率不够高。还好静态构造函数只会被执行一次。希望本文能够起到抛砖引玉的作用。如果您有更好的方案,欢迎和我交流。我的联系方式:sam1111@citiz.net
今天调用一个Web Services的时候,碰到了“System.Net.WebException: The underlying connection was closed: Unable to connect to the remote server.”错误。比较妖的是,我用WinForm调用是成功的,而当我用WebForm的时候,却碰到了上面的异常。上网搜了半天,发现很多人遇到这个异常,可是却没有标准的解法,一般有下面几种方法可以试试:
1.如果用了代理,设置正确。
2.如果用了firewall,将firewall禁掉试试。
3.将Lan设置中的Automatically Detect Settings禁掉。
4.重装.Net Framework。
起初我以为不是Proxy的问题,因为WinForm可以成功。于是试了2和3,都没有什么效果,对于4我实在不大想重装.Net Framework。于是抱着试试看的想法,在代码里用WebProxy为WebServices对象加了个proxy,没想到问题竟然就此解决了
转自:http://www.umlchina.com/News/Content/39.htm
---------------------------------------------------------------------------------------------------------------------
Web service已经不再是新婚的娘子。众多企业都已经创建各种实验性Web Services 项目,事实证明,这项新兴的分布式计算技术确实能够降低集成和开发的成本。另外,一些关键的Web Services标准纷纷制定,强安全(robust security)和管理方面的产品也陆续问世。对于志向远大的企业来说,他们已经在考虑下一步了。
对大多数公司来说,下一步要考虑的不再是点对点的应用,而是Web services在企业间以及业务伙伴间更为宽广的应用。这种技术的变迁需要更松散耦合、面向基于标准的服务的架构。这样一个架构要求对IT在组织中的角色有新的观点和认识,而不仅仅是一种实现方法。通过对业务的敏捷反应,企业可以得到实实在在的回报,而要达到这一点,面向服务架构设计师的角色非常关键。除此之外,潜在的回报更是不可胜数-分布计算技术能够保证对业务需求足够灵活的反应,而这种业务上的敏捷正是各公司梦寐以求而目前还遥不可及的。
分布式计算将网络上分布的软件资源看作是各种服务。面向服务架构是一种不错的解决方案。但这种架构不是什么新思想;CORBA和DCOM就很类似,但是,这些过去的面向服务架构都受到一些难题的困扰:首先,它们是紧密耦合的,这就意味着如分布计算连接的两端都必须遵循同样API的约束。打比方说,如果一个COM对象的代码有了更改,那么访问该对象的代码也必须作出相应更改。其二,这些面向服务架构受到厂商的约束。Microsoft控制DCOM自不必说,CORBA也只是一个伪装的标准化努力,事实上,实现一个CORBA架构,经常都是在某个厂商对规范的实现上进行工作。
Web services是在改进DCOM和CORBA缺点上的努力。今天应用Web services的面向服务架构与过去不同的特点就在于它们是基于标准以及松散耦合的。广泛接受的标准(如XML和SOAP)提供了在各不同厂商解决方案之间的交互性。而松散耦合将分布计算中的参与者隔离开来,交互两边某一方的改动并不会影响到另一方。这两者的结合意味着公司可以实现某些Web services而不用对使用这些Web services的客户端的知识有任何了解。我们将这种基于标准的、松散耦合的面向服务的架构简称为SOA。
SOA的强大和灵活性将给企业带来巨大的好处。如果某组织将其IT架构抽象出来,将其功能以粗粒度的服务形式表示出来,每种服务都清晰地表示其业务价值,那么,这些服务的顾客(可能在公司内部,也可能是公司的某个业务伙伴)就可以得到这些服务,而不必考虑其后台实现的具体技术。更进一步,如果顾客能够发现并绑定可用的服务,那么在这些服务背后的IT系统能够提供更大的灵活性。
但是,要得到种强大和灵活性,需要有一种实现架构的新方法,这是一项艰巨的任务。企业架构设计师必须要变成“面向服务的架构设计师”,不仅要理解SOA,还要理解SOA的实践。在架构实践和最后得到的架构结果之间的区别非常微妙,也非常关键。本文将讨论SOA的实践,即:面向架构的设计师在构建SOA时必须要做的事情。
SOA的原则
SOA是一种企业架构,因此,它是从企业的需求开始的。但是,SOA和其它企业架构方法的不同之处在于SOA提供的业务敏捷性。业务敏捷性是指企业对变更快速和有效地进行响应、并且利用变更来得到竞争优势的能力。对架构设计师来说,创建一个业务敏捷的架构意味着创建这样一个IT架构,它可以满足当前还未知的业务需求。
要满足这种业务敏捷性,SOA的实践必须遵循以下原则:
* 业务驱动服务,服务驱动技术
从本质上说,在抽象层次上,服务位于业务和技术中间。面向服务的架构设计师一方面必须理解在业务需求和可以提供的服务之间的动态关系,另一方面,同样要理解服务与提供这些服务的底层技术之间的关系。
* 业务敏捷是基本的业务需求
SOA考虑的是下一个抽象层次:提供响应变化需求的能力是新的“元需求”,而不是处理一些业务上的固定不变的需求。从硬件系统而上的整个架构都必须满足业务敏捷的需求,因为,在SOA中任何的瓶颈都会影响到整个IT环境的灵活性。
* 一个成功的SOA总在变化之中
SOA工作的场景,更象是一个活的生物体,而不是象传统所说的“盖一栋房子”。IT环境唯一不变的就是变化,因此面向服务架构设计师的工作永远不会结束。对于习惯于盖房子的设计师来说,要转向设计一个活的生物体要求崭新的思维方式。如下文所写的,SOA的基础还是一些类似的架构准则。
SOA基础
在IT行业有两个越来越普遍的发展方向,一个是架构方面的,一个是方法学方面的,面向服务的架构设计师可以从中有所收获。第一个就是MDA(模型驱动架构),由提出CORBA的OMG模型提出。MDA认为架构设计师首先要对待创建的系统有一个形式化的UML(也是由OMG提出)的模型。MDA首先给出一个平台无关的模型来表示系统的功能需求和use cases,根据系统搭建的平台,架构设计师可以由这个平台无关的模型得到平台相关的模型,这些平台相关模型足够详细,以至于可以用来直接生成需要的代码。
MDA的核心就在于在设计阶段系统就已经完全描述,这样,在创建系统的时候,几乎就没有错误解释的可能,模型也就可以直接生成代码。但MDA有一些局限性:首先,MDA假设在创建模型之前,业务需求已经全部描述,而这一点,在当前典型的动态业务环境中几乎是不可能的。第二,MDA没有一个反馈机制。如果开发人员对模型有需要改动的地方,并没有提供给他们这么一个途径。
SOA的另一个基础是敏捷方法(AM),其中非常有名的方法是极限编程(XP)。象XP这样的AM提供了在需求未知或者多变的环境中创建软件系统的过程。XP要求在开发团队中要有一个用户代表,他帮助书写测试来指导开发人员的日常工作。开发团队中的所有成员都参与到设计之中,并且设计要尽量小并且非形式化。AM的目标是仅仅创建用户想要的,而不是在一些形式化模型上耗费工作量。AM的核心思想就在于其敏捷性-处理需求变更的敏捷性。AM的主要弱点是其规模上的限制,例如,XP在一个小团队和中型项目中效果不错,但是当项目规模增大时,如果没有一个一致的清晰的计划,项目成员很难把握项目中的方方面面。
从表面看来,MDA和AM似乎是相对立的-MDA假定需求是固定的,而AM恰恰相反。MDA的中心是形式化的模型,而AM恰恰要避开它们。但是,我们还是决定冒险把这些不同方法中的一些元素提取出来,放入到一个一致的架构实践中。
在SOA中有三个抽象层次,按照SOA的第一条准则:业务驱动服务、服务驱动技术。AM将业务模型直接和实践连接起来,表现在平台相关的模型之中。MDA并没有把业务模型和平台无关模型分开来,而是把平台无关模型做为起点。SOA必须连接这些模型,或者说抽象层次,得到单一的架构方法。我们将从五个视图的架构实现方法来实现这个连接。
SOA的五视图实现方法
企业架构设计师发现他们的职业非常有竞争力并且值得骄傲,因为他们要从很多方面来通盘考虑IT系统。Kruchten(RUP的开发负责人)将这些方面提取出来,在应用到SOA时,我们称为五视图实现方法(five-view approach)。
四个方框表示对一个架构的不同审视方法,分别代表不同的涉众(stakeholder)。弟五个视图,use-case视图涵盖了其它视图,在架构中扮演的是一个特殊的角色。部署视图将软件映射到底层平台和相关硬件上,是系统部署人员对架构的视图;实现视图描述了软件代码的组织,是从开发人员角度出发的视图;业务分析人员则利用过程视图进行工作,它描述的是软件系统的运行时特性。最后,逻辑视图表示的是用户的功能需求。在SOA中,面向服务的架构必须能够以use-case视图中的用例将用户连接到服务,将服务连接到底层的技术。
为了表示面向对象的架构是如何工作在这些视图之上,让我们将他们置于SOA元模型的上下文之中。SOA中两个领域存在重叠:由业务模型和服务模型表示的业务领域和由服务模型及平台相关模型表示的技术领域(两个领域共享服务模型)。业务用户通过逻辑视图和过程视图处理粗粒度的业务服务,根据变化的业务需求,按照需要将它们安排在过程之中。另一方面,技术专家的工作是创建并维护服务和地层技术之间的抽象层。表示这些服务的中间模型,起到的是轴心的作用,业务以它为中心进行。
SOA元模型从MDA中继承平台无关模型和平台相关模型,但是添加了AM和用户交互以及敏捷的反馈这两部分,后者通过椭圆之间的双向箭头来表现。类似地,元模型通过引入由中心的服务模型提供的中间层抽象解决了AM在伸缩性方面的问题。这样,服务模型中的任何需求的变化,都会反映到用户每天的业务处理中。同样,由于底层技术是模型驱动的,技术专家也可以根据这些变化的需求迅速而有效地作出应变。
SOA实践和过去解决企业架构传统方式的不同之处就在于其对敏捷性的支持。如前所说,SOA的第三条原则就在于它总在变化之中。这种恒在的变化性环境是SOA实践的基石。如图所示,涉众(stakeholders,译者注:RUP中也有这个词,表示软件开发中涉及到的各种角色如:用户、设计人员、开发人员乃至测试人员等等。)在一个必需的基础上影响到整个架构的变化。在当技术专家在每天的日常工作中不断对变化的业务需求作出响应的这种情况下,设计阶段和运行阶段之间的界限变得模糊起来,很难清晰地分离这两个阶段。
剩下的部分
我们已经为面向服务的架构提供了一个高层次的框架,其中MDA和AM的元素帮助工具的使用者来创建和维护SOA。但是,SOA中还缺少一些内容-那就是软件开发商和专业的服务组织必需提供的。理想情况下,开发商必需提供面向服务的业务流程、工作流以及服务的协调工具和服务;另外,能够以一种敏捷的、平台无关的方式充分反映业务服务的建模工具也是必须的;技术专家必须配备可以从模型中自动生成代码,并在代码变化时更新模型的工具,最后,开发商必须提供支持SOA的软件,帮助面向服务的架构设计师以一种可信并且可伸缩的方式创建位于服务和底层技术之间的抽象层次。幸运的是,这方面的产品即将上市。
另外,最重要的就是贯穿本文的自顶而下的SOA实现方法了。今天关于Web services的大部分思考都是自底而上的:“这是如何创建Web services的方法,现在,我们来使用它们集成吧”,对Web services技术的这种方法是伟大的第一步,因为它可以惊人地降低集成的开销,这是现在的技术管理人员最乐意见到的了。但当经济进一步发展,IT走出低谷,企业会寻求IT的帮助来提高组织战略意义上的核心价值。使用面向服务的架构,IT可以提供给企业实现业务敏捷性的这样一个框架。
转自:http://www.e-works.net.cn/ewkArticles/Category228/Article16015.htm
---------------------------------------------------------------------------------------------------------------------
随着业务的增长,为了保持自己的竞争优势,企业信息化得到了迅速发展,大量新的技术得到了应用。由于企业的需求很难准确表述和度量,许多具备通用功能的软件,不能满足用户的全部需求,因此,很多项目是严格按照客户提出的功能来设计的。
这种方式一个很大的缺陷在于:不同的应用系统之间很难进行通讯,受特定的通讯方式的限制。随着信息化的发展,目前,企业考虑到业务整合的时候,就出现了困难,用户感觉到项目的整体费用和项目的复杂性,不能很好地进行控制。
面向服务的集成正是根据这个需求,所产生的。
1 面向服务的体系结构(SOA)
SOA(Service Oriented Architecture,面向服务的体系结构)来源于早期的基于构件的分布式计算方式,在OMG和IONA的推动下,成为了一个大家所广泛认可的规范。90年代,CORBA和微软的COM编程模式,促进了SOA的发展。随着Java编程语言、EJB构件模式的发布以及J2EE应用服务市场的成熟,SOA得到了进一步发展。
理论上,面向服务的体系结构这种思想,在其简易性上,十分吸引人。如果你能够用定义很好的机构封装应用,就有可能将一个单一的应用加入到一个服务的集合中。封装的过程创建了一个抽象的层,屏蔽了应用中复杂的细节(你将不用关心用的是哪一种编程语言,什么操作系统,应用程序用的是什么数据库产品)。唯一相关的时就是服务所描述的接口。
SOA的优势在于高可复用性,灵活性,以及更好的扩展性和可用性。经过15年的软件体系结构的创新,在一系列应用开发项目中,SOA的优点得到了体现。
SOA的首次尝试,只是用于新的业务逻辑的开发,只提供有限的功能,而系统的主体部分,并不采用面向服务的原理构建。另外,竞争和创新意味着多样的,不同的SOA实现方式使得集成没那么容易。
统一采用一种方案,共同获取这是不可能做到的。因此现实世界中,需要能够融合各种差异。吸引早期的教训,各方供应商最终将聚在一起,为SOA提供一个更好的框架。
2 面向服务的集成(SOI)
SOI(Service-Oriented Integration,面向服务的集成)将传统的集成对象与开放的、高灵活性的Web Services整合在一起。面向服务的集成提供了一个抽象的接口,通过这些接口,系统可以进行交互,而不是使用低层的协议和自定义的编程接口,来规定系统如何与其它系统进行通讯。系统只需要以服务的形式出现,选择与该系统交互的其它系统,能够简单发现那些服务,并且在运行的时候或者是设计的时候,与这些服务绑定。
以前业务方面的应用程序,仍然可以使用,但是由于缺少现代的接口,不能被重用。对于IT机构而言,这是一个挑战,需要去适应新的通讯和访问方式,比如网络或是更高的桌面环境产品,如微软的.net。
面向服务的集成使得IT机构能够在已有的应用中提供可重用的服务的功能。
对于一个集成项目,所要花费的相关费用,基本上可以分为四个阶段:初始阶段费用,定制阶段费用,维护阶段费用以及后期变更所需要的费用。不同的集成方式,在各个阶段的费用大体如图1所示。

从图1的比较可以看出,虽然在定制阶段,SOI的费用会比其他类型的集成方式要高,但是,从维护阶段以及后期的变更所需的费用来看,采用SOI可以大幅降低项目的相关费用。
3 SOI与Web Services的比较
Web Services是基于互联网的应用程序模块,用于在互联网上运行,采用开放的UDDI(Universal Description,Discovery and Integration,通用描述,发现,集成)标准。UDDI标准先由IBM、微软、Ariba制订,到目前为止获得了130多家公司的支持。UDDI提供了一个开放,平台独立的技术框架,来使企业之间能在互联网上找到对方的服务,定义它们在互联网上的交互活动,以及这些信息的共享方式。Web Services并不特指某一公司的产品,服务或开发工具(如微软ASP.Net中的Web Services),而是指在各种协议集下大家共同遵守的基于互联网络的编程平台。
SOI通过提供一个构建、部署和管理集成的体系框架,简化了系统的集成。SOI和“基本”的Web Services使用的是相同的标准集合。
虽然相似,但是由于SOI需要适当的特征,用于更广的度量以及EAI(Enterprise Application Integration,企业应用集成),这就使得SOI已经超出“基本”的Web Services的范畴。具体表现为以下几个方面:
① 能够提供服务。SOI使用标准的接口来展现已有的系统。因为这些已有的系统是生产业务应用,他们不能被改变;SOI必须支持非入侵的服务。
② 支持多种传输方式。Web Services规范中并不要求明确的传输方式,虽然Web服务常被误认为只是通过HTTP方式进行传输。事实上是WSDL(Web Services Description Language,Web服务描述语言)和SOAP(Simple Object Access Protocol,简单对象获取协议)规范讨论了多种的传输方式。
③ SOI方案必须整合各种不同的企业架构体系(包括MQSeries,CORBA, Tuxedo, TIBCO, JMS等各种企业级产品),因此,对上述主要协议的支持,是SOI方案中的基本要求。
④ 安全性。在评估一个企业集成的技术这个问题上,安全性越来越受到人们的重视。通常情况下,被集成的资源中都有他们自身的安全模式(这些安全模式,可能在开发过程中就已经设计好了)。要想能够被用于集成,SOI方案必须支持基于角色的访问协议,单用户签名,服务使用者与服务提供者之间的安全交换,必须能够集成现有的企业安全系统。
⑤ 对事务的支持。Web Services标准并未指定事务的模型。虽然现在有很多公司正在拟制Web服务事务模型的规范草稿。
为了能够使企业客户接受,SOI方案中必须支持事务的语义(包括commit和roll back等特征)。
⑥ 支持会话的交互。许多企业系统是基于客户/服务器之间的会话交互方式,因为对于事实相应要求更高的系统来说,这种方式的效率更高。为了便于扩展,SOI必须支持会话的交互。
4 小结
面向服务的集成,可以减少不同类型的IT系统的依赖性,降低费用和IT操作的复杂性,提高已部署系统的灵活性。这个新的方式超出了传统集成的范围,能够合理化地将有用的技术进行合并,同时排除了抑制业务创新的障碍。
今天是我第一次面试别人。在今天之前我只被别人面试过,而从没有面试过别人。我对如何面试应聘者的所有经验,就是公司前两天进行的一次关于Interview的内部培训。
我今天是应聘者所要面对的第一位技术人员,我感觉自己今天比较紧张,面试过程中总是想着培训的内容,和应聘者聊的内容比较生硬,搞的应聘者也紧张起来了。总的感觉我今天还是比较失败的,我怕是我的原因而使应聘者不能很好的发挥,所以我pass了所有应聘者,使得二面的负担比较重
我的面试结束后去旁听了一个同事的面试过程,他和应聘者聊的非常好,应聘者在他那里明显的放松很多,他们一起在白板上讨论问题,甚至由于意见不一而发生了争执。我觉得这样非常棒。看来我还有很多要学的
不知道大家在Interview这方面有什么经验?一起分享分享
那天多事,在china-pub上写了一条关于《C++ Templates中文版》的评论,没想到却引发了一场口水仗。不但被人指是侯捷的Fans,更被人认为是“无聊的批评者”。
其实我的本意到不是想说jjh的比chenweizhu的翻译的好,只是就事论事地响应了一下为这本书找错误的活动,没想到某些人的反应却着实让我吃惊。看来以后还是三缄其口的好。
在MSDN上看到一个Quake II for .NET的下载,从介绍上看,微软主要是想通过它来表现Visual C++.Net在处理C++ unmanaged code和managed code方面的强大之处。
我以前一直认为C#是最适合写.Net程序的语言,大概看过Quake II for .NET之后发现,似乎Visual C++.NET才是最强大的
今天在查看自己随笔的引用时,发现了这样一个地方:
http://www.flashanywhere.net/mxna/index.cfm
上面汇集了许多blog,包括我们博客堂各位的
看到沉思辣椒关于建模工具的随笔,发现大家似乎很少使用Visio来建模,其实象各位MVP这样有MSDN订阅的人,完全可以使用Visio。我个人觉得现在的建模工具都很不完善,没必要花钱买
推荐一本讲Visio建模的书:Professional UML with Visual Studio .NET