`

AOP:使用命令模式实现AOP

阅读更多
原帖地址:http://www.cnblogs.com/happyframework/archive/2013/06/06/3120410.html

背景


某位大牛说过,采用命名模式的好处是,你可以将命令按照不同的方式执行,如:排队、异步、远程和拦截等等。今天我介绍一下如何拦截命令的执行,这有些AOP的味道。


思路


就是一个管道过滤器而已



实现


核心代码


命令接口



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Command
8 {
9 /// <summary>
10 /// 命令接口。
11 /// </summary>
12 public interface ICommand
13 {
14 }
15 }


命令处理器接口,一个命令只能有一个命令处理器。



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Command
8 {
9 /// <summary>
10 /// 命令处理器接口,一个命令只能有一个命令处理器。
11 /// </summary>
12 public interface ICommandHandler<TCommand>
13 where TCommand : ICommand
14 {
15 /// <summary>
16 /// 处理命令。
17 /// </summary>
18 void Handle(TCommand command);
19 }
20 }


命令执行上下文接口,代表了一次命令的执行过程。



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Command
8 {
9 /// <summary>
10 /// 命令执行上下文接口,代表了一次命令的执行过程。
11 /// </summary>
12 public interface ICommandExecuteContext
13 {
14 /// <summary>
15 /// 命令执行服务。
16 /// </summary>
17 ICommandService CommandService { get; }
18
19 /// <summary>
20 /// 正在执行的命令。
21 /// </summary>
22 ICommand Command { get; }
23
24 /// <summary>
25 /// 执行下一个<see cref="CommandInterceptorAttribute"/>,如果已经是最后一个,就会执行<see cref="ICommandHandler{TCommand}"/>
26 /// </summary>
27 void ExecuteNext();
28 }
29 }


命令拦截器,拦截正在被执行的命令。



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Happy.Command
{
/// <summary>
/// 命令拦截器,拦截正在被执行的命令。
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public abstract class CommandInterceptorAttribute : Attribute
{
/// <summary>
/// 构造方法。
/// </summary>
/// <param name="order">指示拦截器在管道中的位置</param>
protected CommandInterceptorAttribute(int order)
{
this.Order = order;
}

/// <summary>
/// 拦截正在被执行的命令。
/// </summary>
/// <param name="context">命令执行上下文</param>
public abstract void Intercept(ICommandExecuteContext context);

/// <summary>
/// 拦截器在管道中的位置。
/// </summary>
public int Order { get; protected set; }
}
}


管道过滤器的内部实现



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Command.Internal
8 {
9 internal sealed class CommandInterceptorChain
10 {
11 private ICommandExecuteContext _commandExecuteContext;
12 private CommandInterceptorAttribute[] _commandInterceptors;
13 private Action _commandExecutor;
14 private int _currentCommandInterceptorIndex = -1;
15
16 internal CommandInterceptorChain(
17 ICommandExecuteContext commandExecuteContext,
18 CommandInterceptorAttribute[] commandInterceptors,
19 Action commandExecutor)
20 {
21 _commandExecuteContext = commandExecuteContext;
22 _commandInterceptors = commandInterceptors.OrderBy(x => x.Order).ToArray();
23 _commandExecutor = commandExecutor;
24 }
25
26 private CommandInterceptorAttribute CurrentCommandInterceptor
27 {
28 get
29 {
30 return _commandInterceptors[_currentCommandInterceptorIndex];
31 }
32 }
33
34 internal void ExecuteNext()
35 {
36 _currentCommandInterceptorIndex++;
37
38 if (_currentCommandInterceptorIndex < _commandInterceptors.Length)
39 {
40 this.CurrentCommandInterceptor.Intercept(_commandExecuteContext );
41 }
42 else
43 {
44 _commandExecutor();
45 }
46 }
47 }
48 }


事务拦截器



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Transactions;
7
8 namespace Happy.Command
9 {
10 /// <summary>
11 /// 事务拦截器。
12 /// </summary>
13 public sealed class TransactionAttribute : CommandInterceptorAttribute
14 {
15 /// <inheritdoc />
16 public TransactionAttribute(int order) : base(order) { }
17
18 /// <inheritdoc />
19 public override void Intercept(ICommandExecuteContext context)
20 {
21 using (var ts = new TransactionScope())
22 {
23 context.ExecuteNext();
24
25 ts.Complete();
26 }
27 }
28 }
29 }


应用事务拦截器



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 using Happy.Domain;
8 using Happy.Command;
9 using Happy.DesignByContract;
10
11 namespace Happy.Application
12 {
13 /// <summary>
14 /// 简单的创建命令。
15 /// </summary>
16 [Transaction(1)]
17 public abstract class SimpleCreateCommand<TAggregateRoot> : SimpleCommand<TAggregateRoot>
18 where TAggregateRoot : AggregateRoot
19 {
20 }
21 }


执行命令



 1         /// <summary>
2 /// 创建。
3 /// </summary>
4 public ActionResult Create(TAggregateRoot item)
5 {
6 this.CurrentCommandService.Execute(new TCreateCommand
7 {
8 Aggregate = item
9 });
10
11 return this.NewtonsoftJson(new
12 {
13 success = true,
14 items = this.GetById(item.Id)
15 });
16 }


备注


这里的命令模式本质上是一种消息模式,因为命令里没有任何行为,将行为独立了出来。像WCF、ASP.NET和ASP.NET MVC本质上也是消息模式,他们也内置了管道过滤器模式。


 

本文链接

分享到:
评论

相关推荐

    第四章:Spring AOP API 设计模式1

    15. **命令模式(Command)**:命令模式在Spring AOP中可能并不直接体现,但在Spring MVC中,控制器方法可以看作命令对象,负责处理请求。 16. **状态模式(State)**:状态模式在Spring AOP中不是直接应用,但可以...

    java 命令模式实例 (设计模式)

    在Java中,许多库和框架都使用了命令模式,例如Swing中的ActionListener接口,以及Spring框架的AOP(面向切面编程)中的通知模型。 总结一下,命令模式提供了一种方式来将请求封装为独立的对象,使得请求的发送者和...

    app aop code withbug

    4. **错误排查**:在遇到AOP代码问题时,需要熟悉调试技巧,例如设置断点、查看日志输出、使用AspectJ的debug模式等,来定位错误发生的具体位置和原因。 5. **Gradle集成**:由于文件列表中有`build.gradle`,说明...

    Redis+lua+AOP实现简单的限流

    本篇文章将详细讲解如何利用Redis、Lua脚本以及AOP(面向切面编程)来实现一个简单的限流策略。Redis是一个高性能的键值存储系统,而Lua则可以作为其内置的脚本语言执行复杂逻辑,AOP则是编程设计模式的一种,允许...

    Java与模式pdf

    4. **行为型模式**:包括策略模式、模板方法模式、观察者模式、迭代器模式、职责链模式、命令模式、备忘录模式、状态模式、访问者模式和解释器模式,它们主要处理对象之间的交互和责任分配。 5. **Java语言特性与...

    内容综述1

    3. **Spring缓存抽象(Caching Abstract)**:使用AOP实现缓存功能,提高应用程序性能。 4. **Spring本地调度(Scheduling)**:利用AOP处理定时任务。 理解并掌握Spring AOP对于开发高效的Spring应用程序至关重要...

    新版设计模式手册 - C#设计模式(第二版)

    比如命令模式、解释器模式、迭代器模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。C#的事件和委托系统使得实现如观察者模式变得非常直观。 在C#设计模式(第二版)中,作者可能会...

    设计模式问答(2)Java开发Java经验技巧共18页.p

    10. **命令模式**:命令模式将请求封装为一个对象,以便使用不同的请求、队列请求、或者支持撤销操作。在GUI编程中,命令模式常用于实现撤销/重做功能。 这些设计模式的掌握对于提升Java开发者的技能和编写高质量、...

    24种设计模式以及混合设计模式

    如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、访问者模式(Visitor)、备忘录模式(Memento)、状态模式(State)、职责链...

    JAVA设计模式

    14. 命令模式(Command):命令模式将请求封装为一个对象,以便使用不同的请求、队列请求、支持撤销操作。Java的`java.lang.Runnable`接口以及Swing的Action类都是命令模式的体现。 15. 责任链模式(Chain of ...

    java设计模式中英文各种版本打包下载 学习设计模式必备材料

    3. 行为型模式(Behavioral Patterns):如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、迭代器模式(Iterator)、责任链模式(Chain of Responsibility)、命令模式(Command...

    设计模式项目需要用的Jar

    结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式和享元模式)以及行为型模式(如策略模式、模板方法模式、观察者模式、访问者模式、职责链模式、命令模式、解释器模式、迭代器模式、...

    Java 中的设计模式 - jdon

    命令模式(Command),将请求封装为一个对象;迭代器模式(Iterator)用于顺序访问聚合对象的元素;模板方法模式(Template Method)定义操作中的算法骨架,而将一些步骤延迟到子类中;还有职责链模式(Chain of ...

    23种设计模式-手写代码实现「纯手工代码」

    AOP(面向切面编程)使用代理模式实现;事件驱动机制则基于观察者模式等。 在"23种设计模式_手写代码实现「纯手工代码」"的压缩包文件中,可能包含了使用SpringBoot框架实现这23种设计模式的示例代码。通过学习这些...

    设计模式Design(最有用版

    最后,行为型模式涉及对象之间的责任分配和交互,如策略模式、模板方法模式、观察者模式、职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、状态模式、访问者模式和访问者模式。 在...

    设计模式可复用面向对象软件的基础

    主要包括策略模式、模板方法模式、观察者模式、迭代器模式、访问者模式、职责链模式、命令模式、解释器模式和备忘录模式。 二、设计模式的应用价值 1. 提高代码可读性和可维护性:设计模式为常见的问题提供了标准...

    aop 多切面配置demo

    在Java开发领域,AOP(Aspect Oriented Programming,面向切面编程)是一种强大的设计模式,它允许程序员将关注点从核心业务逻辑中分离出来,如日志、事务管理、性能监控等。Spring框架是实现AOP的一个流行选择,它...

    Delphi模式编程-配书光盘源码

    4. **行为型模式编程**:行为型模式主要关注对象间的通信和责任分配,包括策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、访问者模式(Visitor)、命令模式(Command)、迭代器...

    java设计模式的分析及其应用

    - 命令模式(Command):将请求封装为一个对象,以便使用不同的请求、队列请求或记录请求。 - 解释器模式(Interpreter):提供一种方式来表示语言的语法,并解释执行。 - 迭代器模式(Iterator):提供一种方法...

    设计模式:Java语言中的应用.zip

    包括策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、备忘录模式(Memento)、状态模式(State)、访问者模式(Visitor)、责任链...

Global site tag (gtag.js) - Google Analytics