提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
系列 :AOP多种实现方式 七大原则,24种设计模式,aop多种实现方式_云草桑的博客-CSDN博客
前言
AOP面向切面编程,是OOP的补充,why?
一、AOP是什么?AOP解决什么问题?
Aspect Oriented Programming
AOP
面向切面编程,是
OOP
的补充,
why
?
写代码怕的不是功能复杂,怕的是变化
---MySQL
切换到
SQLServer---
面向对象的
常见套路:
IDBHelper
抽象
---
实现多个版本
---
通过工厂
/IOC
去获取实例
----
避免上
层代码的修改
---But
,这里的
扩展靠的是类的替换,以类为单位,类本身是没有扩
展的
!
--
面向对象里面设计模式
80%
靠的都是这招
----why
?因为类是
OOP
的最小
单位,是他的根基,所以不能动!
有局限!
---Save
的时候写个日志,来个
try-catch---OOP
能做还是类替换
---
但是如
果这个扩展功能希望能随便增减,随便排序
---OOP
就真的搞不定了
---
原因在于类
是固定的,是写死的
---
变态需求
:既不破坏现有封装,又能扩展新功能
—
答案就
是
AOP
面向切面编程
二、AOP演进历史
1.AOP历史
从
POP
到
OOP
POP
Procedure Oriented Programming
POP
面向过程编程,事物比较简单,
可以用
线性的思维
去解决问题。
/// <summary>
/// POP面向过程编程
/// </summary>
public class POPShow
{
/// <summary>
/// 模拟用户注册,3个步骤
/// 面向过程式编程
/// 线性思维的体现
/// 不能应对变化
/// </summary>
public static void Show()
{
Console.WriteLine("用户注册,提交信息");
Console.WriteLine("1 参数检查");
Console.WriteLine("2 数据入库");
Console.WriteLine("3 记录日志");
}
}
OOP
Object Oriented Programming
OOP
面向对象编程是一种编程思想,
是考虑问题的方式
/// <summary>
/// OOP面向对象编程演练
/// </summary>
public class OOPShow
{
/// <summary>
/// OOP面向对象编程
/// 1 考虑有几个对象
/// 2 封装屏蔽细节
/// 3 还可以继承完成代码复用
/// 4 支持多态,尤其是面向抽象编程
///
/// 内部升级---面向对象的内部还是面向过程的
/// </summary>
public static void Show()
{
Console.WriteLine("用户注册,提交信息");
UserInfo userInfo = new UserInfo()
{
Account = "Administrator",
Name = "Eleven",
Password = "888888"
};
//还可以把校验也封装
if (userInfo.Account == null)
{
Console.WriteLine("注册失败");
return;
}
//MySQLDBHelper dbHelper = new MySQLDBHelper();
//封装好了---但是有需求变更,增加日志、异常处理、缓存---只有2种方式:
//1 修改方法---破坏封装,影响稳定性,违背开闭原则
//2 面向抽象---来个新的类实现,然后替换一下,类似于IOC---大功告成---
//但这就是OOP的局限性!只能以类为单位来做拓展,因为类是OOP的组成原子,不容修改--但是扩展需求,就只能抽象+替换类(90%设计模式)----
//有没有这么一个玩法:既不破坏类的封装(也不替换类),但又能扩展功能,有!这个就叫AOP
//AOP是OOP的补充,用来扩展OOP对象通用功能(非业务功能)---
IDBHelper dbHelper = SimpleFactory.CreateDBHelper();//当然也可以IOC
dbHelper.Save(userInfo);
LogHelper.Log("用户注册成功");
}
}
public class SimpleFactory
{
public static IDBHelper CreateDBHelper()
{
//return new MySQLDBHelper();
return new MysqlDBHelperV2();
//return new SqlServerDBHelper();
}
}
面向切面编程AOP
/// <summary>
/// 面向切面编程AOP
/// </summary>
public class AOPShow
{
public static void Show()
{
{
Console.WriteLine("用户注册,提交信息");
UserInfo userInfo = new UserInfo()
{
Account = "Administrator",
Name = "清光",
Password = "888888"
};
IDBHelper dBHelper = new DBHelperProxy(); //new MySQLDBHelper();
dBHelper.Save(userInfo);
}
{
//动态代理的
DynamicProxy.Show();
//可以动态的为各种类扩展功能,哇 很强大
//1 更灵活的功能扩展,程序设计聚焦于业务逻辑
//2 代码复用,方便维护和团队管理
//AOP能做什么 AOP不能做什么?
//几乎业务逻辑之外的东西,都可以靠AOP实现
//AOP不能做业务逻辑,不能新增业务逻辑,只能扩展通用逻辑---
}
}
}
#region 静态代理
/// <summary>
/// 既没有修改对象 也没有替换对象 但是增加了功能--AOP---静态AOP
/// ----对,我是修改了proxy
/// </summary>
public class DBHelperProxy : IDBHelper
{
private IDBHelper _iDBHelper = new MySQLDBHelper();
private ILogHelper helper = new LogConsole();
private void Before()
{
helper.Log("Prepare Save");
}
public int Save(UserInfo userInfo)
{
Before();
int iResult = _iDBHelper.Save(userInfo);
After();
return iResult;
}
private void After()
{
helper.Log("After Save");
}
}
#endregion
#region 动态代理
/// <summary>
/// 利用 .NetRemoting动态代理
/// .NET Core已经没有了,可以用DispatchProxy代替
///
/// 通过动态代理,完成通用功能的扩展
/// 有了这个之后,AOP是不是就可以实现了!
/// </summary>
public class DynamicProxy
{
public static void Show()
{
UserInfo userInfo = new UserInfo()
{
Account = "Administrator",
Name = "清光",
Password = "888888"
};
{
IDBHelper dBHelper = new MySQLDBHelper();
dBHelper.Save(userInfo);
}
{
IDBHelper dbHelper = new MySQLDBHelper();
dbHelper = TransparentProxy.Create(dbHelper);
dbHelper.Save(userInfo);
}
}
}
/// <summary>
/// 真实代理
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyRealProxy<T> : DispatchProxy
{
public T _Instance = default;
//不同的类 不同的方法 增加不同的扩展----类/方法 上面加特性,这里检测特性
protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
{
//System.Reflection.Emit
//IP检测---HttpContext---权限检测
BeforeProceede(targetMethod);//Log try-catch
Console.WriteLine($"This is {targetMethod?.Name}-Invoked");
if (args != null & args.Length > 0)
Console.WriteLine($"参数信息:{JsonConvert.SerializeObject(args)}");
var result = targetMethod?.Invoke(_Instance, args);
Console.WriteLine("方法自身被调用");
//日志---性能统计---缓存一下--事务/异常处理
AfterProceede(targetMethod);
return result;
}
public void BeforeProceede(MethodInfo? targetMethod)
{
Console.WriteLine("方法执行前可以加入的逻辑");
}
public void AfterProceede(MethodInfo? targetMethod)
{
Console.WriteLine("方法执行后可以加入的逻辑");
}
}
/// <summary>
/// 透明代理
/// </summary>
public static class TransparentProxy
{
public static T Create<T>(T t)
{
dynamic tProxy = DispatchProxy.Create<T, MyRealProxy<T>>()!;
tProxy!._Instance = t;
return tProxy;
}
}
#endregion
2.AOP 应用
代码如下(示例):
try
{
Console.WriteLine("AOP代码演进");
{
//Console.WriteLine("*************POPShow**********");
//POPShow.Show();
//Console.WriteLine();
//Console.WriteLine("*************OOPShow**********");
//OOPShow.Show();
//Console.WriteLine();
//Console.WriteLine("*************AOPShow**********");
//AOPShow.Show();
//Console.WriteLine();
}
{
CastleAOPShow.Show();
}
}
catch (Exception)
{
throw;
}
总结
AOP
的价值
AOP
面向切面编程,通过预编译或者运行时动态代理的方式,做到既不破坏现有
封装,又能扩展新功能,是
OOP
补充
AOP
能带来什么好处?
1
方便扩展,可以轻松扩展各种通用功能:日志、安全、缓存、异常处理、参
数检查
and so on ------Filter
2
开发时可以聚焦在业务逻辑,然后通过
AOP
的形式扩展通用功能,还能集中
维护通用功能模块
------Filter
以上就是今天要讲的内容,本文仅仅简单介绍了AOP的使用,而AOP提供了大量能使我们快速便捷地处理编程。