2013-08-21 42 views
6

Một lớp dynamic proxy là một lớp mà thực hiện một danh sách các giao diện quy định tại thời gian chạy như vậy mà một phương pháp gọi thông qua một trong những giao diện trên một thể hiện của lớp sẽ được mã hóa và gửi đi để một đối tượng khác thông qua một giao diện thống nhất. Nó có thể được sử dụng để tạo đối tượng proxy loại an toàn cho danh sách giao diện mà không cần yêu cầu tạo lớp proxy trước. Lớp proxy động là hữu ích cho ứng dụng hoặc thư viện cần cung cấp loại an toàn invocations trên đối tượng mà hiện giao diện API enter image description hereTại sao chúng ta sử dụng động Proxy

trên hình là mẫu tốt nhưng Tại sao chúng ta sử dụng proxy động?

Có một ví dụ đơn giản nào sử dụng trong thế giới thực, để có thêm nhận thức không?

+1

IMO câu hỏi này là quá rộng, bạn nên chia câu hỏi này trong các vấn đề riêng biệt – onof

+0

@onof Ok cảm ơn –

Trả lời

0

link này mô tả proxy năng động trong mã:

public static class DynamicProxyGenerator 
{ 
    public static T GetInstanceFor<T>() 
    { 
     Type typeOfT = typeof(T); 
     var methodInfos = typeOfT.GetMethods(); 
     AssemblyName assName = new AssemblyName("testAssembly"); 
     var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.RunAndSave); 
     var moduleBuilder = assBuilder.DefineDynamicModule("testModule", "test.dll"); 
     var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "Proxy", TypeAttributes.Public); 

     typeBuilder.AddInterfaceImplementation(typeOfT); 
     var ctorBuilder = typeBuilder.DefineConstructor( 
        MethodAttributes.Public, 
        CallingConventions.Standard, 
        new Type[] { }); 
     var ilGenerator = ctorBuilder.GetILGenerator(); 
     ilGenerator.EmitWriteLine("Creating Proxy instance"); 
     ilGenerator.Emit(OpCodes.Ret); 
     foreach (var methodInfo in methodInfos) 
     { 
      var methodBuilder = typeBuilder.DefineMethod( 
       methodInfo.Name, 
       MethodAttributes.Public | MethodAttributes.Virtual, 
       methodInfo.ReturnType, 
       methodInfo.GetParameters().Select(p => p.GetType()).ToArray() 
       ); 
      var methodILGen = methodBuilder.GetILGenerator();    
      if (methodInfo.ReturnType == typeof(void)) 
      { 
       methodILGen.Emit(OpCodes.Ret); 
      } 
      else 
      { 
       if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum) 
       { 
        MethodInfo getMethod = typeof(Activator).GetMethod(/span>"CreateInstance",new Type[]{typeof((Type)});       
        LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType); 
        methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType); 
        methodILGen.Emit(OpCodes.Call, typeofype).GetMethod("GetTypeFromHandle")); )); 
        methodILGen.Emit(OpCodes.Callvirt, getMethod); 
        methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType); 

       } 
       else 
       { 
        methodILGen.Emit(OpCodes.Ldnull); 
       } 
       methodILGen.Emit(OpCodes.Ret); 
      } 
      typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); 
     } 

     Type constructedType = typeBuilder.CreateType(); 
     var instance = Activator.CreateInstance(constructedType); 
     return (T)instance; 
    } 
} 
+0

Đây là một triển khai C# cụ thể, nhưng không nói đến các ứng dụng có thể có o f mẫu – STW

+0

Như tôi đã nói: Liên kết này mô tả proxy động trong mã. và nó đã làm cho nó rất rõ ràng với bản thân mình vì vậy tôi nghĩ rằng nó có thể là một câu trả lời thực tế tốt cho câu hỏi. –

3

Trường hợp sử dụng phổ biến là dành cho Aspect-Oriented Programming, trong đó bạn tìm cách áp dụng chức năng phổ biến trên một số thành phần mà không yêu cầu các thành phần tự thực hiện chức năng. Trong những trường hợp này, bạn có thể sử dụng proxy động để bao bọc tất cả các thành phần nhắm mục tiêu với hành vi bổ sung. Làm như vậy

Một vài ví dụ:

  • ORMs như Hibernate và Entity Framework làm điều này để cung cấp một thực hiện kiên trì xung quanh một thiết kế mã đầu tiên. Các lớp miền chính được xây dựng mà không có bất kỳ kiến ​​thức nào về sự kiên trì của chúng và các khung công tác sẽ bao bọc hoặc mở rộng các lớp này khi khởi động để xử lý việc triển khai thực tế.

  • Bao gói tất cả các thành viên của giao diện với một khía cạnh như ghi nhật ký hoặc lưu vào bộ nhớ cache. Ví dụ, nếu bạn muốn ghi lại mọi lời gọi phương thức trên ISomeInterface, bạn có thể viết một proxy động tìm tất cả các phương thức giao diện, gọi phương thức Log với các chi tiết phương thức, và sau đó chuyển cuộc gọi đến thực hiện thực tế.

2

Hãy tưởng tượng bạn có hai đối tượng Ô tô và Thuyền máy triển khai giao diện CanDrive và CanFloat tương ứng. Bây giờ, bạn muốn có một đối tượng thứ ba thực hiện cả hai giao diện đó và sử dụng lại logic từ Car và Motorboat. Trong các ngôn ngữ như Groovy, Ruby và Scala bạn có thể giải quyết bằng cách sử dụng mixin. Tuy nhiên, trong Java, không có thứ gì như vậy. Tất nhiên bạn có thể sử dụng ví dụ Mẫu thiết kế bộ điều hợp, nhưng trong nhiều trường hợp (đặc biệt là khi xây dựng các khung công tác) proxy động có ích. Hãy xem xét các ví dụ sử dụng thư viện cglib:

CanDrive car = new Car(); 
CanFloat motorboat = new Motorboat(); 

net.sf.cglib.proxy.Mixin amphibian = net.sf.cglib.proxy.Mixin.create(new Object[] { car, motorboat }); 

TestCase.assertEquals("bzzz bzzz bzzz ...", ((CanFloat) amphibian)._float()); 
TestCase.assertEquals("pyr pyr pyr pyr ...", ((CanDrive) amphibian).drive()); 
Các vấn đề liên quan