C# .Net AOP 演进历史POP OOP 代码细节篇

64 篇文章 2 订阅
8 篇文章 0 订阅

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

系列 :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提供了大量能使我们快速便捷地处理编程。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云草桑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值