design pattern proxy介紹 20130805
TRANSCRIPT
Design Pattern-Proxy介紹
演說者:林政融日期: 2013/08/05
AgendaC#的 Design Pattern
◦Creational Patterns◦Structural Patterns◦Behavioral Patterns
Design Pattern – ProxyDynamic Proxy
C#的 Design Pattern
Creational PatternsAbstract Factory Creates an instance
of several families of classesBuilder Separates object construction
from its representationFactory Method Creates an instance
of several derived classesPrototype A fully initialized instance
to be copied or clonedSingleton A class of which only a
single instance can exist
Structural PatternsAdapter Match interfaces of different classesBridge Separates an object’s interface from its
implementationComposite A tree structure of simple and
composite objectsDecorator Add responsibilities to objects
dynamicallyFaçade A single class that represents an entire
subsystemFlyweight A fine-grained instance used for
efficient sharingProxy An object representing another
object
Behavioral PatternsChain of Resp. A way of passing a request
between a chain of objectsCommand Encapsulate a command request
as an objectInterpreter A way to include language
elements in a programIterator Sequentially access the elements
of a collectionMediator Defines simplified communication
between classesMemento 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
DefinitionProvide 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 ProxySituation: 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 ProxyAdvantage: easy to revise the
original methodDisadvantage: 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.aspxhttp://www.codeproject.com/Articles/5511/Dynamic-Proxy-Creation-Using-C-Emit