首页 技术 正文
技术 2022年11月14日
0 收藏 669 点赞 5,088 浏览 3394 个字

一、AOP概念

AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。OOP是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系;AOP是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。AOP是使用切面(aspect)将横切关注点模块化,OOP是使用类将状态和行为模块化。在OOP的世界中,程序都是通过类和接口组织的,使用它们实现程序的核心业务逻辑是十分合适。但是对于实现横切关注点(跨越应用程序多个模块的功能需求)则十分吃力,比如日志记录,权限验证,异常拦截等。

    设计的目的往往是对修改封闭,对扩展开放。也就是现有的功能不去修改,这样减少错误发生。AOP就是将公用功能提取出来,如果以后公用功能的需求发生变化,只需要改动公用的模块的代码即可,多个调用的地方则不需要改动。所谓面向切面,就是只关注通用功能,而不关注业务逻辑。实现方式一般是通过拦截。比如,我们随便一个Web项目基本都有的权限验证功能,进入每个页面前都会校验当前登录用户是否有权限查看该界面,我们不可能说在每个页面的初始化方法里面都去写这段验证的代码,这个时候我们的AOP就派上用场了,AOP的机制是预先定义一组特性,使它具有拦截方法的功能,可以让你在执行方法之前和之后做你想做的业务,而我们使用的时候只需要的对应的方法或者类定义上面加上某一个特性就好了。

  AOP是对OOP思想的一个补充和丰富,对于一些通用的逻辑和单元处理的封装。比如每个功能都有验证用户登录这种纵向分部的问题,可以通过基类的方式解决,但是比如异常处理、日志处理,缓存处理等水平分部的功能,是无法通过继承解决的。

二、使用AOP的优势

1、将通用功能从业务逻辑中抽离出来,可以省略大量重复代码,有利于代码的操作和维护。

2、在软件设计时,抽出通用功能(切面),有利于软件设计的模块化,降低软件架构的复杂度。也就是说通用的功能都是一个单独的模块,在项目的主业务里面是看不到这些通用功能的设计代码的。

上文引用自:https://www.cnblogs.com/lihuali/p/6288859.html

三、通过装饰器模式实现静态拦截

public class User
{
  public int Id { get; set; }
  public string Name { get; set; }
}
public interface IRegUser
{
  void RegUser(User user);
}
public class RegService : IRegUser
{
  public void RegUser(Models.User user)
  {
    Console.WriteLine("注册用户成功……");
  }
}
  /// <summary>
/// 装饰器
/// </summary>
public class RegServiceDecorator : IRegUser
{
IRegUser regUserService;
public RegServiceDecorator(IRegUser RegService)
{
regUserService = RegService;
} public void RegUser(Models.User user)
{
Validate(user); regUserService.RegUser(user); Log(user);
}
/// <summary>
/// 业务执行前的验证
/// </summary>
/// <param name="user"></param>
private void Validate(Models.User user) {
Console.WriteLine("验证模型");
}
/// <summary>
/// 业务执行后的日志
/// </summary>
/// <param name="user"></param>
private void Log(Models.User user) {
Console.WriteLine("写日志");
}
}  class Program
{
public static void Main(string[] args)
{
IRegUser regService = new Contract.RegService();
regService = new RegServiceDecorator(regService);
regService.RegUser(new User() { Id = , Name = "lvcc" });
}
  }

四、AOP在Unity中的实现

第一步,添加Unity及相关组件的引用

面相切面编程AOP以及在Unity中的实现

    public class User
{
public int Id { get; set; }
public string Name { get; set; }
} public interface IRegUser
{
[UserCheck]
void RegUser(User user);
} public class RegService : IRegUser
{
public void RegUser(Models.User user)
{
Console.WriteLine("注册用户成功……");
}
}
/// <summary>
/// 用于标记的属性
/// </summary>
public class UserCheckAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new UserCheckHandler() { };
}
}
/// <summary>
/// 将实际业务方法前后包一层的函数
/// </summary>
public class UserCheckHandler : ICallHandler
{
public int Order { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
#region 包在业务方法之前
User userModel = input.Inputs[] as User;
if (string.IsNullOrEmpty(userModel.Name))
{
//return input.CreateExceptionMethodReturn(new Exception("姓名不能为空"));
Console.WriteLine("姓名不能为空");
}
Console.WriteLine("model验证通过");
#endregion #region 调用接口自己的业务方法
IMethodReturn method = getNext()(input, getNext); #endregion #region 包在业务方法之后
Console.WriteLine("");
#endregion
return method;
}
}
class Program
{
public static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();//生成Unity容器 container.AddNewExtension<Interception>();//添加拦截器
container.RegisterType<IRegUser, RegService>().Configure<Interception>()
.SetInterceptorFor<IRegUser>(new InterfaceInterceptor());//注册接口实现类、配置拦截器的类型、为具体接口设置拦截器
;
//调用
IRegUser regUserService = container.Resolve<IRegUser>(); regUserService.RegUser(new User() { Id = , Name = "lvcc" }); Console.ReadLine();
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,031
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,860