|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
因为各系统的API不同,代码调用API编写程序就会遇到很多不兼容的地方,比如Java改写后的Serv-U就不能在手机上执行,手机的游戏也不能直接在微机上执行。静态 弁言
假设如今我们有如许在这个示例中我将利用尽量复杂的逻辑完成一切功效需求,这将更凸起我们所要办理的中心成绩。例子是一个复杂盘算器类:
publicclassCalculator
{
publicintAdd(intx,inty){returnx+y;}
}
这个类再复杂不外了,不外若你将它设想为一个大概更庞大的营业处置类的时分,你将面对除中心功效完成以外的更多处置细节,好比说:权限把持、审计日记、功能监测、缓冲处置、事件情况等等。为复杂起见,我们起首为该类增添纪录日记的功效,该功效请求将对每一个办法的挪用和处置了局输入到Console中,以下:
publicclassCalculator
{
publicintAdd(intx,inty)
{
Console.Write("Add({0},{1})",x,y);
intresult=x+y;
Console.WriteLine("={0}",result);
returnresult;
}
}
再复杂不外了,对吧?如今我们必要为该办法完成功能监测,以下:
publicclassCalculator
{
publicintAdd(intx,inty)
{
Console.Write("Add({0},{1})",x,y);
DateTimeTimeBegin=System.DateTime.Now;
intresult=x+y;
TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
Console.Write("[{0}]",TimeInter);
Console.WriteLine("={0}",result);
returnresult;
}
}
此时你已感到到,固然我们完成了所需的功效,可是在一个办法中堆叠了处置各种事件的分歧代码。固然在这个复杂例子中不会感到有甚么不爽,可是请你设想一下假如我们将为该类增加第二个办法时会产生甚么事变:
publicclassCalculator
{
publicintAdd(intx,inty)
{
Console.Write("Add({0},{1})",x,y);
DateTimeTimeBegin=System.DateTime.Now;
intresult=x+y;
TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
Console.Write("[{0}]",TimeInter);
Console.WriteLine("={0}",result);
returnresult;
}
publicintSubtract(intx,inty)
{
Console.Write("Subtract({0},{1})",x,y);
DateTimeTimeBegin=System.DateTime.Now;
intresult=x-y;
TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
Console.Write("[{0}]",TimeInter);
Console.WriteLine("={0}",result);
returnresult;
}
}
在两个办法中已分明呈现反复代码了,这可不是一个好的办理举措――想一想一下假如我们的盘算器有10个办法呢?假如我们另有相似于盘算器类的别的数十个类呢?假如我们另有更多的办法级功效要完成呢(权限把持、事件办理……)?在企业级使用开辟中,这但是一个常常会遇的成绩。为分明起见,我们将成绩分化成两部分,主要的成绩是代码职责搅浑,其次则是一样的代码逻辑重复屡次――这些成绩都将招致开辟办理、代码编写与保护的各类坚苦。
计划一:本人手动编写代办署理办理
1、起首我们界说接口ICalculator:
usingSystem;
namespaceProxy
{
publicinterfaceICalculator
{
intAdd(intx,inty);
intSubtract(intx,inty);
}
}
2、详细完成一个接口:
usingSystem;
namespaceProxy
{
publicclassCalculator:ICalculator
{
publicvirtualintAdd(intx,inty)
{
intresult=x+y;
returnresult;
}
publicvirtualintSubtract(intx,inty)
{
intresult=x-y;
returnresult;
}
}
} 3、编写增添日记和功能检测功效的代办署理类
增添纪录日记的功效,即功效请求将对每一个办法的挪用和处置了局输入到Console;增添功能监测。
有两种完成体例,正文了个中的一种
usingSystem;
namespaceProxy
{
/////<summary>
/////CalProxy的择要申明。
/////</summary>
//publicclassCalProxy:ICalculator
//{
//privateCalculator_Calculator;
//publicCalProxy()
//{
//this._Calculator=newCalculator();
//}
//privateDateTimeTimeBegin=System.DateTime.Now;
//privatevoidPreDoSomething(intx,inty)
//{
//TimeBegin=System.DateTime.Now;
//Console.Write("Number({0},{1})
",x,y);
//}
////完成add
//publicvirtualintAdd(intx,inty)
//{
//this.PreDoSomething(x,y);
//intresult=this._Calculator.Add(x,y);
//this.PostDoSomething(result);
//returnresult;
//}
////完成sub
//publicvirtualintSubtract(intx,inty)
//{
//this.PreDoSomething(x,y);
//intresult=this._Calculator.Subtract(x,y);
//this.PostDoSomething(result);
//returnresult;
//}
//privatevoidPostDoSomething(intresult)
//{
//TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
//Console.Write("运转工夫[{0}]
",TimeInter);
//Console.WriteLine("运转了局={0}
",result);
//}
//}
///<summary>
///CalProxy的择要申明。
///</summary>
publicclassCalProxy:Calculator
{
publicCalProxy()
{}
privateDateTimeTimeBegin=System.DateTime.Now;
privatevoidPreDoSomething(intx,inty)
{
TimeBegin=System.DateTime.Now;
Console.Write("Number({0},{1})
",x,y);
}
//完成add
publicoverrideintAdd(intx,inty)
{
this.PreDoSomething(x,y);
intresult=base.Add(x,y);
this.PostDoSomething(result);
returnresult;
}
//完成sub
publicoverrideintSubtract(intx,inty)
{
this.PreDoSomething(x,y);
intresult=base.Subtract(x,y);
this.PostDoSomething(result);
returnresult;
}
privatevoidPostDoSomething(intresult)
{
TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
Console.Write("运转工夫[{0}]
",TimeInter);
Console.WriteLine("运转了局={0}
",result);
}
}
}
4、外界的挪用体例
ICalculatorICal=newProxy.CalProxy();
ICal.Add(5,3);
ICal.Subtract(7,2);
运转程序的了局:
Number(5,3)
运转工夫[00:00:02.0156250]
运转了局=8
Number(7,2)
运转工夫[00:00:03]
运转了局=5
计划二:经由过程利用Castle.DynamicProxy,完成Iinterceptor办理
步骤1,2与办理成绩
3、完成StandardInterceptor,增添日记和功能监测功效
StandardInterceptor是接口Iinterceptor的一个完成类,我们完成StandardInterceptor
usingSystem;
usingSystem.Collections;
usingCastle.DynamicProxy;
namespaceProxy
{
///<summary>
///ProxyInterceptor拦阻器完成了日记和功能监测
///</summary>
publicclassProxyInterceptor:StandardInterceptor
{
privateSystem.DateTimeTimeBegin=System.DateTime.Now;
publicProxyInterceptor()
{}
protectedoverridevoidPostProceed(IInvocationinvocation,refobjectreturnValue,paramsobject[]arguments)
{
TimeSpanTimeInter=System.DateTime.Now-TimeBegin;
Console.Write("运转工夫[{0}]
",TimeInter);
Console.WriteLine("运转了局={0}
",returnValue);
base.PostProceed(invocation,refreturnValue,arguments);
}
protectedoverridevoidPreProceed(IInvocationinvocation,paramsobject[]args)
{
Console.Write("Number({0},{1})
",args[0],args[1]);
TimeBegin=System.DateTime.Now;
base.PreProceed(invocation,args);
}
publicoverrideobjectIntercept(IInvocationinvocation,paramsobject[]args)
{
PreProceed(invocation,args);
objectretValue=invocation.Proceed(args);
PostProceed(invocation,refretValue,args);
returnretValue;
}
}
}
4、利用Castle.DynamicProxy挪用
ProxyGeneratorgenerator=newProxyGenerator();
objectproxy=generator.CreateClassProxy(typeof(Calculator),newProxyInterceptor());
ICalculatorICalCastle=proxyasICalculator;
ICalCastle.Add(5,3);
ICalCastle.Subtract(7,2);
完成历程:起首经由过程代码天生完成一个代办署理类,该代办署理类承继自要织进的类。然后在代办署理类中掩盖要拦阻的办法,并在掩盖的办法中封装Invocation工具,并传给用户传进的Intercepter工具的Intercept办法。在Intercept办法顺次挪用Intercepter的PreProcess,经由过程Invocation传进的Delegate指向的回调函数,Intercepter的PostProcess办法,从而到达拦阻的目标。
意义
在aop范畴能够将日记,事件,缓存等附加功效用此完成。它有很多缺点的,有兴趣可以到网上去搜索一下。于是微软有发明了“下一代”C++:C++/CLI语言,这个可以解决在.NETFramework中,托管C++产生的问题。在《程序员》杂志上,lippman和李建中合作连载介绍了C++/CLI语言。 |
|