1、HTTP:最自由的公开方式,适用于多种不同的架构;

2、TCP:一个快速的二进制格式协议,但只适于局域网内部;

3、命名管道(Name Pipes): 一种快速、可靠的交互方式,但只适用于客户端与服务端在同一台机器上,并且只能是WCF-WCF的方式;

4、MSMQ: 由于MSMQ的消息中转特性,因此这种协议支持客户端与服务端非联机工作;

5、自定义协议:极少数场合使用。 

posted @ 2011-04-01 14:27 Sam Zhang 阅读(122) 评论(0) 编辑

对于Schema的任何变更都敏感时,合同的任意变更都需要指定新的版本。

对于Schema并没有精确的要求时,需要注意以下几点:

1、可以在任何时间增加新方法;

2、不能删除任何一个已有的方法;

3、参数的数据类型必须保证向前兼容性。 

posted @ 2011-03-30 15:11 Sam Zhang 阅读(80) 评论(0) 编辑
请求-响应模式(Request - Response)

 最常用模式:

1、客户端请求服务端;

2、服务端返回信息给客户端。 

 

单向模式(One - Way)

 客户端把数据发到服务端即终止调用过程。优势:

1、支持异步调用;

2、用MSMQ来保证调用过程中发生意外时能再次调用。

实现方法:

1、用返回类型为void的方法(C#)或用Sub过程(VB.net);

2、在定制特性OperationContract中设置IsOneWay=true。

 

复杂通知模式(Duplex Messaging)

这个“复杂”的含义仅仅是服务端要临时充当客户端来回调发起请求的客户端的接口方法。 

 

 

流模式(Streaming )

用于获取大量数据的场景,服务端把返回的数据分割成多份传输给客户端。 

 

发布-订阅模式(Pub - Sub)

客户端调用服务端订阅接口。同时客户端把回调的接口信息告知服务端,服务端依据客户端提供的回调接口信息来分发数据。

大多数情况下提供信息的应用并不管理订阅与分发数据的工作,而由单独的Web服务来做这些事情。

 

隐式顺序调用模式(Implied Order Invocation)

定义一组存在逻辑顺序的接口。WCF在定制特性OperationContract中提供了IsInitiating与IsTerminating设置来实现这一模式。

另外,所有Web服务接口方法默认都是设置了IsInitiating=true,IsTerminating=false。

 

 

posted @ 2011-03-10 17:27 Sam Zhang 阅读(108) 评论(0) 编辑

导入导出文件(Import/export files)

优点:适用于在封闭式架构的应用之间传输信息。

缺点:严重依赖于文件传输通道。 

共享数据库(Shared database)

优点:比第一种方式实时性更高。

缺点:集成的应用依赖于数据库结构,应用对数据表结构的变更非常敏感。

RPC(Remote procedure calls)

优点:适用于集成大量应用的场景。 

缺点:各个集成进来的应用过于依赖RPC调用,任何新的应用集成都需要调整已有的相关应用的RPC客户端代码。

消息巴士 / 服务巴士(Message Bus / Service Bus)

优点:便于应用共享已发布出来的数据,将来发生的应用集成不会影响已经存在的应用集成。

缺点:书中未提及。

posted @ 2011-03-09 17:46 Sam Zhang 阅读(103) 评论(0) 编辑
1、引言
这是我碰到一道面试题,当时时间紧我用的字符串分隔实现的,其具体要求为:
将一非负整数转化为int[],如输入1234得到int[4]{ 1, 2, 3, 4 }。
今晚有兴致运用TDD方法做了个不转字符串的版本,主是依靠浮点数转为整数时丢失小数位值这一特性实现的。
*注:代码编写过程中单元测试与实现代码是相互交替的,并不像下面看到的分隔得那么明显。

2、单元测试:
    [TestFixture]
    
public class IntToArrayHelperTests : IntToArrayHelper
    {
        [Test]
        
public void TestGetNumberAt()
        {
            Assert.AreEqual(
0, GetNumberAt(01));
            Assert.AreEqual(
1, GetNumberAt(11));
            Assert.AreEqual(
1, GetNumberAt(211));
            Assert.AreEqual(
1, GetNumberAt(100011));

            Assert.AreEqual(
2, GetNumberAt(212));
            Assert.AreEqual(
1, GetNumberAt(876543211));
            Assert.AreEqual(
2, GetNumberAt(876543212));
            Assert.AreEqual(
7, GetNumberAt(876543217));
            Assert.AreEqual(
8, GetNumberAt(876543218));
        }

        [Test]
        
public void TestGetDigitCount()
        {
            Assert.AreEqual(
1, GetDigitCount(0));
            Assert.AreEqual(1, GetDigitCount(1));
            Assert.AreEqual(1, GetDigitCount(9));
            Assert.AreEqual(2, GetDigitCount(10));
            Assert.AreEqual(10, GetDigitCount(Int32.MaxValue));
        }

        [Test]
        
public void TestConvert()
        {
            
int[] a = new int[1] { 0 };
            Assert.AreEqual(a, Convert(
0));

            
int[] b = new int[1] { 1 };
            Assert.AreEqual(b, Convert(
1));

            
int[] c = new int[10] { 1234567890 };
            Assert.AreEqual(c, Convert(
1234567890));

            
int[] d = new int[9] { 987654321 };
            Assert.AreEqual(d, Convert(
987654321));

            
int[] max = new int[10] { 2147483647 };
            Assert.AreEqual(max, Convert(Int32.MaxValue));
        }

        [Test]       
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        
public void TestConvertWithNegative()
        {
            Convert(
-1);
        }
    }

3、实现代码:
    public class IntToArrayHelper
    {
        
protected int GetNumberAt(int value, int digit)
        {
            
int contrastNumber = (int)Math.Pow(10, digit);
            
int digitCutter = (int)Math.Pow(10, digit - 1);
            
return (value - value / contrastNumber * contrastNumber) / digitCutter;
        }

        
protected int GetDigitCount(int value)
        {            
            
if (value == 0)
                
return 1;

            
return (int)Math.Log10(value) + 1;
        }

        
public int[] Convert(int value)
        {
            
if (value < 0)
                
throw new ArgumentOutOfRangeException("value""Not less than zero.");            

            
int digitCount = GetDigitCount(value);
            
int[] result = new int[digitCount];

            
for (int i = 0; i < digitCount; ++i)
            {
                
int index = digitCount - i - 1;
                result[index] 
= GetNumberAt(value, i + 1);
            }

            
return result;
        }
    }


posted @ 2007-07-30 23:43 Sam Zhang 阅读(236) 评论(0) 编辑
posted @ 2007-07-20 01:31 Sam Zhang 阅读(491) 评论(0) 编辑
摘要: 摘自《代码大全》(第一版)如果你所编程序出现了问题,这是你自己的过错。这不是计算机也不是编译程序的过失。程序本身不会作某些事情。它不会自己编写自己,而是你编写了它,所以你应对它负责。即使一个错误刚开始似乎不是你的过失,但是你应仍有兴趣弄清楚是否真是这样。这有助于调试,你想找到代码中的错误是困难的,而当你认为你的代码无错时则更是困难。当你宣称某人的代码中存在错误,其它程序员会相信你已对问题进行了仔细检查,这样可能增大你言行不一致的缺点。假设错误是自己的,可使你免受宣称某个错误是别人,而最后发现是你的而不得不改口的窘迫处境。阅读全文
posted @ 2007-07-11 21:24 Sam Zhang 阅读(32) 评论(0) 编辑
posted @ 2007-07-11 21:23 Sam Zhang 阅读(1513) 评论(0) 编辑
摘要: 就像中医可以通过把脉来诊断病情,我们程序员可以通过代码的气味来判断代码是否需要重构。特整理了《重构——改善既有代码的设计》中列出的代码坏味道列表以备忘。阅读全文
posted @ 2007-07-11 21:23 Sam Zhang 阅读(46) 评论(0) 编辑
posted @ 2007-07-11 21:21 Sam Zhang 阅读(155) 评论(0) 编辑