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

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

    • 分享

      結(jié)構(gòu)型模式之代理模式

       新進(jìn)小設(shè)計 2021-07-13

      在有些情況下,一個客戶不能或者不想直接訪問另一個對象,這時需要找一個中介幫忙完成某項任務(wù),這個中介就是代理對象。

      定義與特點

      由于某些原因需要給某對象提供一個代理以控制對該對象的訪問。這時,訪問對象不適合或者不能直接引用目標(biāo)對象,代理對象作為訪問對象和目標(biāo)對象之間的中介。

      主要優(yōu)點有:

      • 代理模式在客戶端與目標(biāo)對象之間起到一個中介作用和保護(hù)目標(biāo)對象的作用。

      • 代理對象可以擴(kuò)展目標(biāo)對象的功能。

      • 代理模式能將客戶端與目標(biāo)對象分離,在一定程度上降低了系統(tǒng)的耦合度。

      主要缺點有:

      • 在客戶端和目標(biāo)對象之間增加一個代理對象,會造成請求處理速度變慢。

      • 增加了系統(tǒng)的復(fù)雜度

      結(jié)構(gòu)與實現(xiàn)

      代理模式的結(jié)構(gòu)比較簡單,主要是通過定義一個繼承抽象主題的代理來包含真實主題,從而實現(xiàn)對真實主題的訪問。

      模式的結(jié)構(gòu)

      代理模式的主要角色如下:

      • 抽象主題(Subject)類:通過接口或抽象類(推薦使用接口)聲明真實主題和代理對象實現(xiàn)的業(yè)務(wù)方法。

      • 真實主題(Real Subject)類:實現(xiàn)了抽象主題中的具體業(yè)務(wù),是代理對象所代表的真實對象,是最終要引用的對象。

      • 代理(Proxy)類:提供了與真實主題相同的接口,其內(nèi)部含有對真實主題的引用,它可以訪問、控制或擴(kuò)展真實主題的功能。

      其結(jié)構(gòu)圖如圖所示:

      模式的實現(xiàn)

      代理模式的實現(xiàn)代碼如下:

      //訪問類
      class Program
      {
          static void Main(string[] args)
          {
              //代理模式        
              Proxy proxy=new Proxy();
              proxy.Request();       
              Console.ReadKey();
          }
      }
      
      //抽象主題
      public interface ISubject
      {
          void Request();
      }
      
      //真實主題
      public class RealSubject :ISubject
      {
          public void Request()
          {
              Console.WriteLine("訪問真實主題方法...");
          }
      }
      
      //代理
      public class Proxy : ISubject
      {
          private RealSubject realSubject;
          public void Request()
          {
              if (realSubject==null)
              {
                  realSubject=new RealSubject();
              }
              PreRequest();
              realSubject.Request();
              PostRequest();
          }
          public void PreRequest()
          {
              Console.WriteLine("訪問真實主題之前的預(yù)處理。");
          }
          public void PostRequest()
          {
              Console.WriteLine("訪問真實主題之后的后續(xù)處理。");
          }
      }

      程序運(yùn)行的結(jié)果如下:

      訪問真實主題之前的預(yù)處理。
      訪問真實主題方法...
      訪問真實主題之后的后續(xù)處理。

      應(yīng)用場景

      前面分析了代理模式的結(jié)構(gòu)與特點,現(xiàn)在來分析以下的應(yīng)用場景:

      • 遠(yuǎn)程代理(Remote Proxy):這種方式通常是為了隱藏目標(biāo)對象存在于不同地址空間的事實,方便客戶端訪問。
        例如,用戶訪問網(wǎng)盤的虛擬硬盤時實際訪問的是網(wǎng)盤空間。

      • 虛擬代理(Virtual Proxy):這種方式通常用于要創(chuàng)建的目標(biāo)對象開銷很大時。
        例如,下載一幅很大的圖像需要很長時間,這時可以先用小比例的虛擬代理替換真實的對象,消除用戶對服務(wù)器慢的感覺。

      • 保護(hù)代理(Protection Proxy):這種方式通常用于控制不同種類客戶對真實對象的訪問權(quán)限。

      • 智能指引(Smart Reference):主要用于調(diào)用目標(biāo)對象時,代理附加一些額外的處理功能。

      智能指引的典型用途包括:

      • 增加計算真實對象的引用次數(shù)的功能,這樣當(dāng)該對象沒有被引用時,就可以自動釋放它;

      • 當(dāng)?shù)谝淮我靡粋€持久對象時,將它裝入內(nèi)存。

      • 在訪問一個實際對象前,檢查是否已經(jīng)鎖定了它,以確保其他對象不能改變它。

      擴(kuò)展:動態(tài)代理模式

      在前面介紹的代理模式中,代理類中包含了對真實主題的引用,這種方式存在兩個缺點:

      • 真實主題與代理主題一一對應(yīng),增加真實主題也要增加代理。

      • 設(shè)計代理以前真實主題必須事先存在,不太靈活。

      采用動態(tài)代理模式可以解決以上問題(如 SpringAOP),C#中可以使用RealProxy實現(xiàn)動態(tài)代理,有兩種方法:
      第一種:只使用RealProxy,不能代理帶out參數(shù)的方法(可能是我沒找到),代碼如下:

      class Program
      {
          static void Main(string[] args)
          {
              Console.WriteLine("***\r\n Begin program - logging with decorator\r\n");
              IRepository<Customer> customerRepository =RepositoryFactory.Create<Customer>();
              var customer = new Customer()
              {
                  Id = 1,
                  Name = "Customer 1",
                  Address = "Address 1"
              };
              customerRepository.Add(customer);
              customerRepository.Update(customer);
              customerRepository.Delete(customer);
              Console.WriteLine("\r\nEnd program - logging with decorator\r\n***");
              Console.ReadLine();
          }
      }
      //客戶類
      public class Customer
      {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Address { get; set; }
      }
      
      //存儲庫接口
      public interface IRepository<T>
      {
          void Add(T entity);
          void Delete(T entity);
          void Update(T entity);
          IEnumerable<T> GetAll();
          T GetById(int id);
      }
      
      //真實儲存庫
      public class Repository<T> : IRepository<T>
      {
          public void Add(T entity)
          {
              Console.WriteLine("Adding {0}", entity);
          }
          public void Delete(T entity)
          {
              Console.WriteLine("Deleting {0}", entity);
          }
          public void Update(T entity)
          {
              Console.WriteLine("Updating {0}", entity);
          }
          public IEnumerable<T> GetAll()
          {
              Console.WriteLine("Getting entities");
              return null;
          }
          public T GetById(int id)
          {
              Console.WriteLine("Getting entity {0}", id);
              return default(T);
          }
      } 
      
      //動態(tài)代理
      class DynamicProxy<T> : RealProxy
      {
          private readonly T _decorated;
          public DynamicProxy(T decorated) : base(typeof(T))
          {
              _decorated = decorated;
          }
          private void Log(string msg, object arg = null)
          {
              Console.ForegroundColor = ConsoleColor.Red;
              Console.WriteLine(msg, arg);
              Console.ResetColor();
          }
          public override IMessage Invoke(IMessage msg)
          {
              var methodCall = msg as IMethodCallMessage;
              var methodInfo = methodCall.MethodBase as MethodInfo;
              Log("In Dynamic Proxy - Before executing '{0}'",methodCall.MethodName);
              try
              {
                  var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
                  Log("In Dynamic Proxy - After executing '{0}' ",methodCall.MethodName);
                  return new ReturnMessage(result, null, 0,methodCall.LogicalCallContext, methodCall);
              }
              catch (Exception e)
              {
                  Log(string.Format("In Dynamic Proxy- Exception {0} executing '{1}'", e),methodCall.MethodName);
                  return new ReturnMessage(e, methodCall);
              }
          }
      }
      
      //存?zhèn)}庫過程,自動執(zhí)行代理
      public class RepositoryFactory
      {
          public static IRepository<T> Create<T>()
          {
              var repository = new Repository<T>();
              var dynamicProxy = new DynamicProxy<IRepository<T>>(repository);
              return dynamicProxy.GetTransparentProxy() as IRepository<T>;
          }
      }

      第二種:使用RealProxy、MarshalByRefObject,可以代理帶out參數(shù)的方法,代碼如下:

      //訪問類
      public class Program
      {
          static void Main(string[] args)
          {
              //動態(tài)代理模式        
              Proxy<ISubject> proxy = new Proxy<ISubject>(new RealSubject());
              ISubject subject = (ISubject)proxy.GetTransparentProxy();
              int arg = 0;
              subject.Request(out arg); 
              Console.WriteLine(arg);
              Console.ReadKey();
          }
      }
      //代理類
      public class Proxy<T> : RealProxy where T: class
      {    
          MarshalByRefObject myMarshalByRefObject;
          public Proxy(MarshalByRefObject realT) : base(typeof(T))
          {        
              myMarshalByRefObject = realT;
          }
          public override IMessage Invoke(IMessage myMessage)
          {        
              IMethodCallMessage myCallMessage = (IMethodCallMessage)myMessage;
              Console.WriteLine("動態(tài)代理方法中:執(zhí)行前");
              IMethodReturnMessage myIMethodReturnMessage = RemotingServices.ExecuteMessage(myMarshalByRefObject, myCallMessage);
              Console.WriteLine("動態(tài)代理方法中:執(zhí)行后");
              return myIMethodReturnMessage;
          }
      }
      
      //抽象主題
      public interface ISubject
      {
          void Request(out int arg);
      }
      
      //真實主題
      public class RealSubject : MarshalByRefObject,ISubject
      {
          public void Request(out int arg)
          {
              arg = 1;
              Console.WriteLine("訪問真實主題方法...");       
          }
      }

      參考資料    

      C#中動態(tài)代理與泛型函數(shù)——CSDN
      面向方面的編程-使用 RealProxy 類進(jìn)行面向方面的編程——MSDN

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多