Upload
learningtech
View
52
Download
3
Embed Size (px)
Citation preview
Design Pattern-Proxy介紹
演說者:林政融
日期:2013/08/05
Agenda
C#的Design Pattern
◦ Creational Patterns
◦ Structural Patterns
◦ Behavioral Patterns
Design Pattern – Proxy
Dynamic Proxy
C#的Design Pattern
Creational Patterns
Abstract Factory Creates an instance of several families of classes
Builder Separates object construction from its representation
Factory Method Creates an instance of several derived classes
Prototype A fully initialized instance to be copied or cloned
Singleton A class of which only a single instance can exist
Structural Patterns
Adapter Match interfaces of different classes
Bridge Separates an object’s interface from its implementation
Composite A tree structure of simple and composite objects
Decorator Add responsibilities to objects dynamically
Façade A single class that represents an entire subsystem
Flyweight A fine-grained instance used for efficient sharing
Proxy An object representing another object
Behavioral Patterns
Chain of Resp. A way of passing a request between a chain of objects
Command Encapsulate a command request as an object
Interpreter A way to include language elements in a program
Iterator Sequentially access the elements of a collection
Mediator Defines simplified communication between classes
Memento Capture and restore an object's internal state
Behavioral Patterns(continue)
Observer A way of notifying change to a number of classes
State Alter an object's behavior when its state changes
Strategy Encapsulates an algorithm inside a class
Template Method Defer the exact steps of an algorithm to a subclass
Visitor Defines a new operation to a class without change
Design Pattern – Proxy
Definition
Provide a surrogate or placeholder for
another object to control access to it.
UML class diagram
Sample Codeusing System;
namespace DoFactory.GangOfFour.Proxy.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Proxy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create proxy and request a service
Proxy proxy = new Proxy();
proxy.Request();
// Wait for user
Console.ReadKey();
}
}
Sample Code(Subject)
/// <summary>
/// The 'Subject' abstract class
/// </summary>
abstract class Subject
{
public abstract void Request();
}
Sample Code(RealSubject)
/// <summary>/// The 'RealSubject' class/// </summary>class RealSubject : Subject{public override void Request(){
Console.WriteLine("Called RealSubject.Request()");}
}
Sample Code(Proxy)/// <summary>
/// The 'Proxy' class
/// </summary>
class Proxy : Subject
{
private RealSubject _realSubject;
public override void Request()
{
// Use 'lazy initialization'
if (_realSubject == null)
{
_realSubject = new RealSubject();
}
_realSubject.Request();
}
}
}
Sample Code2using System;
namespace DoFactory.GangOfFour.Proxy.RealWorld
{
/// <summary>
/// MainApp startup class for Real-World
/// Proxy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create math proxy
MathProxy proxy = new MathProxy();
// Do the math
Console.WriteLine("4 + 2 = " + proxy.Add(4, 2));
Console.WriteLine("4 - 2 = " + proxy.Sub(4, 2));
Console.WriteLine("4 * 2 = " + proxy.Mul(4, 2));
Console.WriteLine("4 / 2 = " + proxy.Div(4, 2));
// Wait for user
Console.ReadKey();
}
}
Sample Code2(IMath)
/// <summary>/// The 'Subject interface/// </summary>public interface IMath{double Add(double x, double y);double Sub(double x, double y);double Mul(double x, double y);double Div(double x, double y);
}
Sample Code2(Math)
/// <summary>
/// The 'RealSubject' class
/// </summary>
class Math : IMath
{
public double Add(double x, double y) { return x + y; }
public double Sub(double x, double y) { return x -y; }
public double Mul(double x, double y) { return x * y; }
public double Div(double x, double y) { return x / y; }
}
Sample Code2(MathProxy)/// <summary>
/// The 'Proxy Object' class
/// </summary>
class MathProxy : IMath
{
private Math _math = new Math();
public double Add(double x, double y)
{
return _math.Add(x, y);
}
public double Sub(double x, double y)
{
return _math.Sub(x, y);
}
public double Mul(double x, double y)
{
return _math.Mul(x, y);
}
public double Div(double x, double y)
{
return _math.Div(x, y);
}
}
}
Dynamic Proxy
Use of Static Proxy
Situation: when do add, save the result to DB
public double Add(double x, double y)
{
var result = _math.Add(x, y);
// Implement the method to save the result to db
save(result);
return result;
}
Static Proxy
Advantage: easy to revise the original
method
Disadvantage: just only revise the
method that use the declared proxy
Dynamic Proxy(Interface)
public interface IProxyInvocationHandler {
Object Invoke( Object proxy,
MethodInfo method,
Object[] parameters );
}
Dynamic Proxy(Impl)Public Object Invoke(Object proxy,
System.Reflection.MethodInfo method,
Object[] parameters)
{
Object retVal = null;
// is invoked, otherwise an exception is thrown indicating they
// do not have permission
if ( SecurityManager.IsMethodInRole( userRole, method.Name ) )
{
// The actual method is invoked
retVal = method.Invoke( obj, parameters );
} else
{
throw new IllegalSecurityException( "Invalid permission to invoke " + method.Name );
}
return retVal;
}
Dynamic Proxy(Impl)Public Object Invoke(Object proxy,
System.Reflection.MethodInfo method,
Object[] parameters)
{
Object retVal = null;
// is invoked, otherwise an exception is thrown indicating they
// do not have permission
if ( SecurityManager.IsMethodInRole( userRole, method.Name ) )
{
// The actual method is invoked
retVal = method.Invoke( obj, parameters );
} else
{
throw new IllegalSecurityException( "Invalid permission to invoke " + method.Name );
}
return retVal;
}
Use of Dynamic Proxypublic interface ITest
{
void TestFunctionOne();
Object TestFunctionTwo( Object a, Object b );
}
public class TestImpl : ITest
{
public void TestFunctionOne()
{
Console.WriteLine( "In TestImpl.TestFunctionOne()" );
}
public Object TestFunctionTwo( Object a, Object b )
{
Console.WriteLine( "In TestImpl.TestFunctionTwo( Object a, Object b )" );
return null;
}
}
Use of Dynamic
Proxy(continue)public class TestBed
{
static void Main( string[] args )
{
ITest test = (ITest)SecurityProxy.NewInstance( new
TestImpl() );
test.TestFunctionOne();
test.TestFunctionTwo( new Object(), new Object() );
}
}
References
http://www.dofactory.com/Default.aspx
http://www.codeproject.com/Articles/5511/Dynam
ic-Proxy-Creation-Using-C-Emit