当前位置: 首页 > news >正文

装饰器模式和 AOP 面向切片编程(设计模式与开发实践 P15)

文章目录

    • 示例
    • AOP

很多时候我们不希望一个类变得非常庞大,生来就包含很多职责。装饰器模式可以动态地给某个对象添加职责,而不会影响从这个类中派生的其他对象

为什么不用继承解决这个问题呢?如果用继承有可能会创造出数量庞大的子类,而如果把子类的属性变成装饰器,就可以灵活自由地组合了,就像天冷了要穿一件衣服等等

示例

从结构上看,Attack 方法进入了一个包装链,先执行火焰技能,再执行了闪电技能

// 定义游戏角色接口
interface ICharacter
{void Attack();
}// 实现游戏角色类
class Character : ICharacter
{public void Attack(){Console.WriteLine("角色进行普通攻击!");}
}// 装饰器基类
abstract class CharacterDecorator : ICharacter
{protected ICharacter character;public CharacterDecorator(ICharacter character){this.character = character;}public virtual void Attack(){character.Attack();}
}// 具体装饰器类:添加火焰技能
class FireDecorator : CharacterDecorator
{public FireDecorator(ICharacter character) : base(character){}public override void Attack(){base.Attack();Console.WriteLine("释放火焰技能!");}
}// 具体装饰器类:添加闪电技能
class LightningDecorator : CharacterDecorator
{public LightningDecorator(ICharacter character) : base(character){}public override void Attack(){base.Attack();Console.WriteLine("释放闪电技能!");}
}class Program
{static void Main(string[] args){// 创建基本角色ICharacter character = new Character();// 添加火焰技能character = new FireDecorator(character);// 添加闪电技能character = new LightningDecorator(character);// 角色进行攻击character.Attack();// 输出结果:// 角色进行普通攻击!// 释放火焰技能!// 释放闪电技能!}
}

AOP

在这里我们使用了 C# 的 PostSharp 包,创建了方法切面监听

当 Attack 执行时,会引发 OnEntry 和 OnExit 生命周期

在分离业务代码和数据统计代码中, AOP 十分有效!

using PostSharp.Aspects;
using System;// 日志记录切面
[Serializable]
public class LogAspect : OnMethodBoundaryAspect
{public override void OnEntry(MethodExecutionArgs args){Console.WriteLine($"[Log] Entering {args.Method.Name}");}public override void OnExit(MethodExecutionArgs args){Console.WriteLine($"[Log] Exiting {args.Method.Name}");}
}// 游戏角色类
public class Character
{[LogAspect] // 应用日志记录切面public void Attack(){Console.WriteLine("Character attacking!");}
}// 使用 AOP 的游戏示例
class Program
{static void Main(string[] args){Character character = new Character();character.Attack();// 输出结果:// [Log] Entering Attack// Character attacking!// [Log] Exiting Attack}
}
http://www.lryc.cn/news/190385.html

相关文章:

  • Git迁移新仓库并保存历史提交记录
  • MySql逗号分割的字段数据分解为多行
  • 共生与共享:线程与进程的关系
  • uniapp app或微信小程序项目使用gite仓库中的图片
  • KUKA机器人如何强制输出或取消数字IO信号?
  • 利用正则表达式进行数据采集和处理
  • javaScript:拖拽效果
  • 【Unity3D编辑器开发】Unity3D中制作一个可以随时查看键盘对应KeyCode值面板,方便开发
  • VUE echarts 柱状图、折线图 双Y轴 显示
  • Django开发之基础篇
  • 在 centos7 上安装Docker
  • 基于SpringBoot的大学城水电管理系统
  • 微信小程序 movable-view 控制长按才触发拖动 轻轻滑动页面正常滚动效果
  • mysql面试题27:数据库中间件了解过吗?什么是sharding jdbc、mycat,并且讲讲怎么使用?
  • DBCO Sata650,二苯并环辛烷Sata650,Seta-650-DBCO
  • JFLASH基本使用总结
  • 具身智能(Embodied AI)
  • C语言的文件写入、读取
  • CART 算法——决策树
  • CF1877A Goals of Victory
  • 018-第三代软件开发-整体介绍
  • 储存数据文本json的读写
  • Java之动态代理的详细解析
  • github Release 下载加速,绿色合法,遥遥领先
  • RabbitMQ消息中间件概述
  • 12V手电钻保护板如何接线演示
  • 基于SpringBoot的教学辅助平台
  • Qt 读写数据流文件(转 CppGuiProgrammingWithQt4)
  • Pygame中将鼠标形状设置为图片2-2
  • GPU 基础知识整理