1、HTTP:最自由的公开方式,适用于多种不同的架构;
2、TCP:一个快速的二进制格式协议,但只适于局域网内部;
3、命名管道(Name Pipes): 一种快速、可靠的交互方式,但只适用于客户端与服务端在同一台机器上,并且只能是WCF-WCF的方式;
4、MSMQ: 由于MSMQ的消息中转特性,因此这种协议支持客户端与服务端非联机工作;
5、自定义协议:极少数场合使用。
对于Schema的任何变更都敏感时,合同的任意变更都需要指定新的版本。
对于Schema并没有精确的要求时,需要注意以下几点:
1、可以在任何时间增加新方法;
2、不能删除任何一个已有的方法;
3、参数的数据类型必须保证向前兼容性。
最常用模式:
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。
导入导出文件(Import/export files)
优点:适用于在封闭式架构的应用之间传输信息。
缺点:严重依赖于文件传输通道。
优点:比第一种方式实时性更高。
缺点:集成的应用依赖于数据库结构,应用对数据表结构的变更非常敏感。
优点:适用于集成大量应用的场景。
缺点:各个集成进来的应用过于依赖RPC调用,任何新的应用集成都需要调整已有的相关应用的RPC客户端代码。
优点:便于应用共享已发布出来的数据,将来发生的应用集成不会影响已经存在的应用集成。
缺点:书中未提及。
这是我碰到一道面试题,当时时间紧我用的字符串分隔实现的,其具体要求为:
将一非负整数转化为int[],如输入1234得到int[4]{ 1, 2, 3, 4 }。
今晚有兴致运用TDD方法做了个不转字符串的版本,主是依靠浮点数转为整数时丢失小数位值这一特性实现的。
*注:代码编写过程中单元测试与实现代码是相互交替的,并不像下面看到的分隔得那么明显。
2、单元测试:
public class IntToArrayHelperTests : IntToArrayHelper
{
[Test]
public void TestGetNumberAt()
{
Assert.AreEqual(0, GetNumberAt(0, 1));
Assert.AreEqual(1, GetNumberAt(1, 1));
Assert.AreEqual(1, GetNumberAt(21, 1));
Assert.AreEqual(1, GetNumberAt(10001, 1));
Assert.AreEqual(2, GetNumberAt(21, 2));
Assert.AreEqual(1, GetNumberAt(87654321, 1));
Assert.AreEqual(2, GetNumberAt(87654321, 2));
Assert.AreEqual(7, GetNumberAt(87654321, 7));
Assert.AreEqual(8, GetNumberAt(87654321, 8));
}
[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] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
Assert.AreEqual(c, Convert(1234567890));
int[] d = new int[9] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Assert.AreEqual(d, Convert(987654321));
int[] max = new int[10] { 2, 1, 4, 7, 4, 8, 3, 6, 4, 7 };
Assert.AreEqual(max, Convert(Int32.MaxValue));
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestConvertWithNegative()
{
Convert(-1);
}
}
3、实现代码:
{
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;
}
}


