乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      InfoQ: 實(shí)現(xiàn)Web Service依賴倒置

       pstn 2007-12-12

      實(shí)現(xiàn)Web Service依賴倒置

      作者 譯者 王翔 發(fā)布于 2007年8月1日 下午10時(shí)49分

      社區(qū)
      .NET
      主題
      設(shè)計(jì),
      Web服務(wù)

      問(wèn)題的提出

      作為面向?qū)ο笤O(shè)計(jì)的一個(gè)基本原則,依賴倒置原則(DIP)在降低模塊間耦合度方面有很好的指導(dǎo)意義,他的基本要求和示意圖如下:

      “高層模塊不應(yīng)該依賴于低層模塊,二者都應(yīng)該依賴于抽象。抽象不應(yīng)該依賴于細(xì)節(jié)。細(xì)節(jié)應(yīng)該依賴于抽象。”

      圖1:直接依賴(I)和依賴關(guān)系倒置(II)

      這么做有什么優(yōu)勢(shì)呢?

      • 降低Client與ConcreteService的耦合度。
      • ConcreteService可以自主的變化,只要符合IService,就可以繼續(xù)被Client使用。即這種變化對(duì)Client透明。
      • 應(yīng)用框架可以Client的上下文為他物色一個(gè)合適的ConcreteService,動(dòng)態(tài)構(gòu)造、動(dòng)態(tài)綁定、運(yùn)行時(shí)動(dòng)態(tài)調(diào)用。

      在單應(yīng)用時(shí)代,基于接口的開(kāi)發(fā)指導(dǎo)了我們養(yǎng)成這種習(xí)慣,但是到了SOA環(huán)境下,通常的Web Service開(kāi)發(fā)情況又是怎么樣呢?

      1. 客戶程序需要調(diào)用某個(gè)Web Service,獲得它的WSDL和相關(guān)數(shù)據(jù)結(jié)構(gòu)的XSD。
      2. 然后客戶程序調(diào)用這個(gè)Web Service,一般情況下如果WSDL不變的話,可以一直使用該Web Service,即便那個(gè)Web Service后面的實(shí)現(xiàn)平臺(tái)發(fā)生變化,但因?yàn)榻壎P(guān)系沒(méi)有變化,所以客戶程序不需要任何修改(偶爾因?yàn)榘姹締?wèn)題,有可能會(huì)進(jìn)行適應(yīng)性調(diào)整)。
      3. 如果發(fā)現(xiàn)有新的相同服務(wù)接口的Service Provider做的不錯(cuò)的化或者把原有Web Service做遷移的話,那就需要重新更新WSDL,編譯新的Web Service Client Proxy類,有可能客戶程序也要重新編譯。

      Web Service很好地隔絕了服務(wù)定義與服務(wù)實(shí)現(xiàn)兩者的關(guān)系,同時(shí)它也把可能的備選功能提供者從內(nèi)部一下子推到整個(gè)互聯(lián)網(wǎng)環(huán)境下,怎么讓客戶程序透明的適應(yīng)眾多可選服務(wù)就成了一個(gè)挑戰(zhàn)。

      怎么辦?老辦法——抽象

      實(shí)現(xiàn)Web Service依賴倒置

      分析

      相信在實(shí)踐設(shè)計(jì)模式的過(guò)程中,開(kāi)發(fā)人員已經(jīng)對(duì)依賴倒置的概念有了深刻的體驗(yàn),“不依賴于具體實(shí)現(xiàn),而是依賴于抽象”,整理SOA環(huán)境下的Web Service一樣需要借鑒這個(gè)概念,筆者將之稱為“Web Service依賴倒置”。大概邏輯結(jié)構(gòu)變成如下:

      圖2:概要Web Service依賴倒置后的邏輯關(guān)系

      但Web Service本身接口是“平的”,沒(méi)有辦法繼承,只有用OO語(yǔ)言把它進(jìn)行包裝之后才可以成為對(duì)應(yīng)的類,這時(shí)候才能有所謂的“繼承”或“接口實(shí)現(xiàn)”;所謂“抽象”既可能是接口也可能是抽象類(當(dāng)然,也可以考慮用實(shí)體基類),所以在處理ConcreteWebService與抽象Web Service的時(shí)候也有兩種方式:

      • 通過(guò)繼承的
      • 通過(guò)單繼承+多接口組合的

      筆者更傾向于后者,因?yàn)橥ㄟ^(guò)組合可以不斷擴(kuò)展。同時(shí)考慮到Web Service使用往往在一個(gè)分布式的環(huán)境中,因此參考RPC中常用的叫法,增加了一一個(gè)Stub(用接口IServiceX表示)和Proxy。修改后依賴倒置的關(guān)系如下:

      圖3:分布式環(huán)境下多組合服務(wù)接口實(shí)現(xiàn)的Web Service依賴倒置

      實(shí)現(xiàn)示例

      1、對(duì)業(yè)務(wù)數(shù)據(jù)建模(XSD):

      假設(shè)業(yè)務(wù)對(duì)象為報(bào)價(jià)信息,報(bào)價(jià)分為報(bào)價(jià)頭和明細(xì)(1:0..n),因此結(jié)構(gòu)如下:

      圖4:報(bào)價(jià)信息的XSD

      XSD
      <?xml version="1.0" encoding="UTF-8"?>
      <xs:schema
        xmlns="http://www./trade"
        xmlns:xs="http://www./2001/XMLSchema"
        targetNamespace="http://www./trade"
        elementFormDefault="qualified"
        attributeFormDefault="unqualified">
          <xs:element name="Quote">
              <xs:annotation>
                  <xs:documentation>Comment describing your root element</xs:documentation>
              </xs:annotation>
              <xs:complexType>
                  <xs:sequence>
                      <xs:element ref="QuoteItem" minOccurs="0" maxOccurs="unbounded"/>
                  </xs:sequence>
                  <xs:attribute name="Id" type="xs:string" use="required"/>
                  <xs:attribute name="Company" type="xs:string" use="required"/>
              </xs:complexType>
          </xs:element>
          <xs:element name="QuoteItem">
              <xs:complexType>
                  <xs:attribute name="ProductId" type="xs:integer" use="required"/>
                  <xs:attribute name="Price" type="xs:double" use="required"/>
                  <xs:attribute name="QuantitiveInStock" type="xs:double"/>
              </xs:complexType>
          </xs:element>
      </xs:schema>

      2、完成XSD與對(duì)象實(shí)體的映射:(XSD to Object)

      Command

      通過(guò)Visual Studio.Net自帶的Xsd.exe進(jìn)行如下操作。


      xsd Quote.xsd /c /n:DemoService

      這樣就生成了結(jié)構(gòu)大概如下的對(duì)應(yīng)的報(bào)價(jià)實(shí)體類:

      C#
      using System;
      using System.Xml.Serialization;
      namespace DemoService
      {
          [System.SerializableAttribute()]
          [XmlTypeAttribute(AnonymousType = true, Namespace = "http://www./trade")]
          [XmlRootAttribute(Namespace = "http://www./trade", IsNullable = false)]
          public partial class Quote
          {
              private QuoteItem[] quoteItemField;
              private string idField;
              private string companyField;
              [XmlElementAttribute("QuoteItem")]
              public QuoteItem[] QuoteItem
              {
                  get { return this.quoteItemField; }
                  set { this.quoteItemField = value; }
              }
              [XmlAttributeAttribute()]
              public string Id
              {
                  get { return this.idField; }
                  set { this.idField = value; }
              }
              [XmlAttributeAttribute()]
              public string Company
              {
                  get { return this.companyField; }
                  set { this.companyField = value; }
              }
          }

          [SerializableAttribute()]
          [XmlTypeAttribute(AnonymousType = true, Namespace = "http://www./trade")]
          [XmlRootAttribute(Namespace = "http://www./trade", IsNullable = false)]
          public partial class QuoteItem
      {
      … …
          }
      }

      3、接著,完成抽象的Web Service定義(optional):

      該步驟的目的是獲取wsdl定義。這里筆者為了省事,用Visual Studio.Net自動(dòng)生成,所以寫(xiě)了個(gè)抽象的Web Service類,實(shí)際開(kāi)發(fā)中完全可以獨(dú)立編寫(xiě)wsdl文件。

      C#
      using System.Web.Services;
      using System.Xml.Serialization;
      namespace DemoService
      {
          [WebService(Name="QuoteService", Namespace="http://www./trade")]
          public abstract class QuoteServiceBase : WebService
          {
              [WebMethod()]
              [return:XmlElement("Quote", Namespace="http://www./trade")]
              public abstract Quote GetQuote(string id);
          }
      }
      WSDL (Quote.wsdl)
      <?xml version="1.0" encoding="utf-8"?>
      <wsdl:definitions xmlns:soap="http://schemas./wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas./soap/encoding/" xmlns:mime="http://schemas./wsdl/mime/" xmlns:tns="http://www./trade" xmlns:s1="http://www./trade" xmlns:s="http://www./2001/XMLSchema" xmlns:soap12="http://schemas./wsdl/soap12/" xmlns:http="http://schemas./wsdl/http/" targetNamespace="http://www./trade" xmlns:wsdl="http://schemas./wsdl/">
        <wsdl:types>
          <s:schema elementFormDefault="qualified" targetNamespace="http://www./trade">
            <s:import namespace="http://www./trade" />
            <s:element name="GetQuote">
              <s:complexType>
                <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1" name="id" type="s:string" />
                </s:sequence>
              </s:complexType>
            </s:element>
            <s:element name="GetQuoteResponse">
              <s:complexType>
                <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1" ref="s1:Quote" />
                </s:sequence>
              </s:complexType>
            </s:element>
      … …
        <wsdl:service name="QuoteService">
          <wsdl:port name="QuoteServiceSoap" binding="tns:QuoteServiceSoap">
            <soap:address location="http://localhost:2401/QuoteServiceBase.asmx" />
          </wsdl:port>
          <wsdl:port name="QuoteServiceSoap12" binding="tns:QuoteServiceSoap12">
            <soap12:address location="http://localhost:2401/QuoteServiceBase.asmx" />
          </wsdl:port>
        </wsdl:service>
      </wsdl:definitions>

      4、生成Web Service接口類型:

      Command

      通過(guò)Visual Studio.Net自帶的Wsdl.exe進(jìn)行如下操作。


      wsdl /n:DemoService /serverinterface /o:IQuoteStub.cs Quote.wsdl Quote.xsd

      這樣就生成了報(bào)價(jià)Web Service的抽象接口:

      C#
      using System.Web.Services;
      using System.Web.Services.Protocols;
      using System.Web.Services.Description;
      using System.Xml.Serialization;
      namespace DemoService
      {
          [WebServiceBindingAttribute(
              Name = "QuoteServiceSoap", Namespace = "http://www./trade")]
          public interface IQuoteServiceSoap
          {
              [WebMethodAttribute()]
              [SoapDocumentMethodAttribute(
                  "http://www./trade/GetQuote",
                  RequestNamespace = "http://www./trade",
                  ResponseNamespace = "http://www./trade",
                  Use = SoapBindingUse.Literal,
                  ParameterStyle = SoapParameterStyle.Wrapped)]
              [return: XmlElementAttribute("Quote",
                  Namespace = "http://www./trade")]
              Quote GetQuote(string id);
          }
      }

      5、生成具體的報(bào)價(jià)Web Service:

      為了示例的方便,IntranetQuoteService自己“手捏”了一票測(cè)試報(bào)價(jià)數(shù)據(jù),至此服務(wù)端Web Service工作基本完成,如果需要使用UDDI則還需要把這個(gè)具體服務(wù)publish出來(lái)。

      C#
      using System;
      using System.Web.Services;
      using System.Web.Services.Protocols;
      namespace DemoService
      {
          /// <summary>
          /// 具體的報(bào)價(jià)Web Service 功能實(shí)現(xiàn)
          /// </summary>
          [WebService(Namespace = "http://www./trade")]
          [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
          public class IntranetQuoteService : WebService, IQuoteServiceSoap
          {
              /// <summary>
              /// 實(shí)現(xiàn)抽象的Web Service調(diào)用
              /// </summary>
              /// <param name="id"></param>
              /// <returns></returns>
              [WebMethod]
              public Quote GetQuote(string id)
              {
                  #region "手捏"出來(lái)的測(cè)試數(shù)據(jù)
                  Quote quote = new Quote();
                  quote.Id = id;
                  quote.Company = "deluxe";

                  QuoteItem[] items = new QuoteItem[2];
                  items[0] = new QuoteItem();
                  items[0].QuantitiveInStockSpecified = true;
                  items[0].ProductId = "Note Bulletin";
                  items[0].Price = 220;
                  items[0].QuantitiveInStock = 10;
                  items[1] = new QuoteItem();
                  items[1].QuantitiveInStockSpecified = true;
                  items[1].ProductId = "Pen";
                  items[1].Price = 3.4;
                  items[1].QuantitiveInStock = 3000;
                  quote.QuoteItem = items;
                  #endregion

                  return quote;
              }
          }
      }

      6、生成客戶端Proxy:

      Command

      通過(guò)Visual Studio.Net自帶的Wsdl.exe進(jìn)行如下操作。


      wsdl /n:Test.Client /o:QuoteProxy.cs Quote.wsdl Quote.xsd

      這樣就生成了報(bào)價(jià)Web Service的客戶端Proxy,他僅通過(guò)最初抽象Web Service的WSDL調(diào)用服務(wù)端Web Service。實(shí)際運(yùn)行過(guò)程中,它并不了解真正使用的時(shí)候是由哪個(gè)服務(wù)提供WSDL中聲明到的“GetQuote”方法。

      C#
      using System.Web.Services;
      using System.Threading;
      using System.Web.Services.Protocols;
      using System.Web.Services.Description;
      using System.Xml.Serialization;
      using DemoService;
      namespace Test.Client
      {
          /// <summary>
          /// Web Service 的客戶端 Proxy
          /// </summary>
          [WebServiceBindingAttribute(
              Name="QuoteServiceSoap",
              Namespace="http://www./trade")]
          public class QuoteService : SoapHttpClientProtocol
          {   
              /// <summary>
              /// 借助 SOAP 消息調(diào)用 Web Service 服務(wù)端
              /// </summary>
              /// <param name="id"></param>
              /// <returns></returns>
              [SoapDocumentMethodAttribute(
                  "http://www./trade/GetQuote",
                  RequestNamespace="http://www./trade",
                  ResponseNamespace="http://www./trade",
                  Use=SoapBindingUse.Literal,
                  ParameterStyle=SoapParameterStyle.Wrapped)]
              [return: XmlElementAttribute("Quote",
                  Namespace="http://www./trade")]
              public Quote GetQuote(string id)
              {
                  object[] results = this.Invoke("GetQuote", new object[] {id});
                  return ((Quote)(results[0]));
              }
          }
      }

      7、客戶程序:

      最后,通過(guò)單元測(cè)試工具檢查的客戶程序如下:

      C#
      using System;
      using DemoService;
      using Microsoft.VisualStudio.TestTools.UnitTesting;
      namespace Test.Client
      {
          /// <summary>
          /// 測(cè)試用客戶程序
          /// </summary>
          [TestClass]
          public class Client
          {
              /// <summary>
              /// 為了簡(jiǎn)化,這里在客戶程序中直接定義了具體報(bào)價(jià)Web Service的Uri.
              /// 實(shí)際開(kāi)發(fā)中該信息應(yīng)該作為服務(wù)端的一個(gè)配置項(xiàng)登記在Directory之中,
              /// 客戶程序僅僅通過(guò)抽象的服務(wù)邏輯名稱從Directory中獲得。)
              /// </summary>
              [TestMethod]
              public void Test()
              {
                  QuoteService service = new QuoteService();
                  service.Url = "http://localhost:2401/IntranetQuoteService.asmx";
                  Quote quote = service.GetQuote("quote:2007-07-15");
                  Assert.AreEqual<string>("quote:2007-07-15", quote.Id);
                  Assert.AreEqual<string>("deluxe", quote.Company);
                  Assert.AreEqual<int>(2, quote.QuoteItem.Length);
                  Assert.IsNotNull(quote.QuoteItem[0]);
              }
          }
      }

      注:為了使用方便,本系列所有示例都沒(méi)有直接采用IIS作為Web Server宿主,而是采用Visual Studio.Net自帶的臨時(shí)服務(wù)進(jìn)程,因此WSDL和Proxy的使用上,相關(guān)端口可能會(huì)變化。

      進(jìn)一步改進(jìn)

      上面的示例在客戶端處理上不算成功,因?yàn)樗枰蛻舫绦蛱峁〤oncreteService的Uri,怎么改進(jìn)呢?回憶我們通常對(duì)連接串的處置辦法:

      • 應(yīng)用邏輯使用一個(gè)邏輯的數(shù)據(jù)庫(kù)名稱,通過(guò)一個(gè)數(shù)據(jù)訪問(wèn)框架調(diào)用邏輯的數(shù)據(jù)庫(kù)。
      • 數(shù)據(jù)訪問(wèn)框架中有一個(gè)類似ConnectionManager的機(jī)制,負(fù)責(zé)把邏輯的數(shù)據(jù)庫(kù)連接名翻譯成實(shí)際的連接串。

      對(duì)上面那個(gè)Web Service示例的也如法炮制,增加一個(gè)邏輯的Directory機(jī)制,實(shí)際工程中這個(gè)Directory可能就是個(gè)UDDI服務(wù),不過(guò)這里定義了一個(gè)精簡(jiǎn)對(duì)象。

      圖5:為客戶程序增加服務(wù)Uri管理目錄機(jī)制

      實(shí)現(xiàn)如下

      C# IServiceDirectory
      using System;
      namespace Test.Client
      {
          /// <summary>
          /// 抽象的服務(wù)目錄接口
          /// </summary>
          public interface IServiceDirectory
          {
              /// <summary>
              /// 通過(guò)索引器實(shí)現(xiàn)按名稱或取實(shí)際服務(wù)Uri 的機(jī)制。
              /// 為了約束客戶程序?qū)Ψ?wù)目錄的使用,僅提供一個(gè)readonly 的訪問(wèn)機(jī)制。
              /// </summary>
              /// <param name="name">邏輯的服務(wù)名稱</param>
              /// <returns>實(shí)際服務(wù)實(shí)體的Uri </returns>
              string this[string name] { get;}
          }
      }
      C# LocalServiceDirectory
      using System;
      using System.Collections.Generic;
      using System.Collections.Specialized;
      using System.Configuration;
      namespace Test.Client
      {
          class LocalServiceDirectory : IServiceDirectory
          {
              /// <summary>
              /// 保存邏輯服務(wù)名稱與具體Uri 對(duì)應(yīng)關(guān)系的目錄字典。
              /// </summary>
              private static IDictionary<string, string> dictionary = null;

              /// <summary>
              /// 靜態(tài)構(gòu)造的過(guò)程中,通過(guò)訪問(wèn)配置,獲取對(duì)應(yīng)關(guān)系。
              /// </summary>
              static LocalServiceDirectory()
              {
                  NameValueCollection appSettings = ConfigurationManager.AppSettings;
                  if ((appSettings == null) || (appSettings.Count <= 0)) return;
                  dictionary = new Dictionary<string, string>();
                  foreach (string name in appSettings.Keys)
                      dictionary.Add(name, appSettings[name]);
              }

              public string this[string name]
              {
                  get
                  {
                      string uri;
                      if (!dictionary.TryGetValue(name, out uri))
                          return string.Empty;
                      else
                          return uri;
                  }
              }
          }
      }
      C# DirectoryServiceFactory
      using System;
      namespace Test.Client
      {
          /// <summary>
          /// 為了隔離客戶程序?qū)?shí)際DirectoryService 類型的以來(lái),引入的服務(wù)目錄工廠。
          /// </summary>
          public static class DirectoryServiceFactory
          {
              /// <summary>
              /// 工廠方法。
              /// 世紀(jì)項(xiàng)目中,實(shí)體ServiceDirectory 類型可能運(yùn)行于遠(yuǎn)端服務(wù)器上,
              /// 或者就是UDDI服務(wù),獲取IServiceDirectory 過(guò)程可能還需要借助代理程序完成。
              /// </summary>
              /// <returns></returns>
              public static IServiceDirectory Create()
              {
                  return new LocalServiceDirectory();
              }
          }
      }
      C# 修改后的客戶程序
      using System;
      using DemoService;
      using Microsoft.VisualStudio.TestTools.UnitTesting;
      namespace Test.Client
      {
          [TestClass]
          public class Client
          {
              [TestMethod]
              public void Test()
              {
                  QuoteService service = new QuoteService();
                  service.Url = DirectoryServiceFactory.Create()["QuoteService"];
        … …
              }
          }
      }

      進(jìn)一步討論

      在有效的隔離了實(shí)體Web Service與抽象Web Service的關(guān)系后,之前設(shè)計(jì)模式、架構(gòu)模式中的那些套路就又有了用武之地,比如Observer、Adapter、Factory、Blackboard、MVC… …,甚至于Visitor這中雙因素以來(lái)的模式也可以套用,只不過(guò)原來(lái)的消息變成了XML SOAP、對(duì)象實(shí)體變成了XSD定義下的各種XML,至于UI上能看到的東西還有需要轉(zhuǎn)換的信息由XSL完成即可。


      作者簡(jiǎn)介:王翔,軟件架構(gòu)師,主要方向?yàn)閄ML技術(shù)、.NET平臺(tái)開(kāi)發(fā)與集成、領(lǐng)域設(shè)計(jì)和公鑰基礎(chǔ)環(huán)境應(yīng)用。近年主要參與數(shù)據(jù)交換系統(tǒng)、自訂制業(yè)務(wù)領(lǐng)域語(yǔ)言平臺(tái)項(xiàng)目和信息安全類項(xiàng)目,工余時(shí)間喜歡旅游、寫(xiě)作、解趣味數(shù)學(xué)問(wèn)題和烹飪。
      加入書(shū)簽
      digg+,
      reddit+,
      del.+,
      dzone+
      標(biāo)簽
      XML

      4 條回復(fù)

      回復(fù)

      或許應(yīng)該更進(jìn)一步的抽象 發(fā)表人 Anders Lin 發(fā)表于 2007年8月2日 下午11時(shí)52分
      Re: 或許應(yīng)該更進(jìn)一步的抽象 發(fā)表人 hello hello 發(fā)表于 2007年8月3日 上午5時(shí)36分
      Re: 或許應(yīng)該更進(jìn)一步的抽象 發(fā)表人 hello hello 發(fā)表于 2007年8月3日 上午5時(shí)36分
      Re: 或許應(yīng)該更進(jìn)一步的抽象 發(fā)表人 hello hello 發(fā)表于 2007年8月3日 上午5時(shí)38分
      1. 返回頂部

        或許應(yīng)該更進(jìn)一步的抽象

        2007年8月2日 下午11時(shí)52分 發(fā)表人 Anders Lin

        目前的抽象僅是隔離Web Service的抽象和實(shí)現(xiàn),或許可以更進(jìn)一步,隔離接口和實(shí)現(xiàn)。接口的實(shí)現(xiàn)是調(diào)用web service還是調(diào)用本地,都不是client關(guān)心的。

      2. 返回頂部

        Re: 或許應(yīng)該更進(jìn)一步的抽象

        2007年8月3日 上午5時(shí)36分 發(fā)表人 hello hello

        確切地說(shuō)現(xiàn)在已經(jīng)是這樣了。
        Client使用的Service其實(shí)不是真正的Service,而是Service的Proxy類。
        是否使用Local,:), 其實(shí)也沒(méi)有關(guān)系,確切地說(shuō)把Assembly放到本地的話,加個(gè)Factory就可以區(qū)分WS還是本地的某Assembly中的某各類。

      3. 返回頂部

        Re: 或許應(yīng)該更進(jìn)一步的抽象

        2007年8月3日 上午5時(shí)36分 發(fā)表人 hello hello

        確切地說(shuō)現(xiàn)在已經(jīng)是這樣了。
        Client使用的Service其實(shí)不是真正的Service,而是Service的Proxy類。
        是否使用Local,:), 其實(shí)也沒(méi)有關(guān)系,確切地說(shuō)把Assembly放到本地的話,加個(gè)Factory就可以區(qū)分WS還是本地的某Assembly中的某各類。

      4. 返回頂部

        Re: 或許應(yīng)該更進(jìn)一步的抽象

        2007年8月3日 上午5時(shí)38分 發(fā)表人 hello hello

        確切地說(shuō)現(xiàn)在已經(jīng)是這樣了。
        Client使用的Service其實(shí)不是真正的Service,而是Service的Proxy類。
        是否使用Local,:), 其實(shí)也沒(méi)有關(guān)系,確切地說(shuō)把Assembly放到本地的話,加個(gè)Factory就可以區(qū)分WS還是本地的某Assembly中的某各類。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多