Qt中的面向切面编程

13

我试图理解面向切面编程(AOP),一些Qt代码会对我有所帮助。

以下是来自维基百科的示例代码(易于Qt/C++程序员阅读):

void transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)
   throws Exception {
   logger.info("transferring money...");
   if (! checkUserPermission(user)){
     logger.info("User has no permission.");
     throw new UnauthorizedUserException();
   }
   if (fromAcc.getBalance() < amount) {
     logger.info("Insufficient Funds, sorry :( ");
     throw new InsufficientFundsException();
   }

   fromAcc.withdraw(amount);
   toAcc.deposit(amount);

   //get database connection

   //save transactions

   logger.info("Successful transaction. :) ");
 }

然后就是"aspectized":

void transfer(Account fromAcc, Account toAcc, int amount) throws Exception {


   if (fromAcc.getBalance() < amount) {
     throw new InsufficientFundsException();
   }

   fromAcc.withdraw(amount);
   toAcc.deposit(amount);
 }

aspect Logger 
{

    void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)
    {
    
        logger.info("transferring money...");
    }

    void Bank.getMoneyBack(User user, int transactionId, Logger logger)
    {
        logger.info("User requested money back");
    }

    // other crosscutting code...
}
Qt有信号和槽用于解耦对象。但我仍然需要发出信号。 所以:这可以使用Qt完成,还是我需要一些特殊的框架/预处理器,如维基百科文章中所述? 我有一种感觉,因为Qt使用元对象编译器,某些功能可能会通过动态方法“注入”...只是想到这里而已;) 编辑:为了给出更好的上下文:我真的很喜欢Qt元对象的动态方面(功率),并希望保持Qt的感觉。因此,我的想法是利用插槽(或信号)作为切入点。例如: 如果我定义slot Bank :: transfer (...),然后定义signal Bank :: OnBeforeTranfer()和signal Bank :: OnAfterTransfer()。然后将它们连接到其他方面,比如Security :: transfer()和Logger :: transfer()(所有QObjects),我可以阻止调用(例如,在BeforeTransfer失败时)。 但是,如果我们将其带到下一个演化阶段以获得更少且更清洁的代码,则希望摆脱OnXXXX信号,并将Bank :: transfer插槽连接到Security :: transfer插槽和Logger :: transfer。 Qt中是否有任何动态内容?例如:调用插槽的顺序以及在“插槽链”中防止下一次调用? 这整个上下文仍然可以认为是AOP吗?我试图坚持“方法级切入点”,还是完全离题了?

基本概念没问题。我只是想看看在Qt中如何实际完成。特别是在“安全方面”(checkUserPermission)应该“阻止”传输时。如果我放置任何IF语句,那么我的代码就不会分离到特定的安全方面... - Derick Schoonbee
另一个不错的例子 https://dev59.com/iXVC5IYBdhLWcg3wnCWA - Derick Schoonbee
你成功了吗?只是出于好奇。 - Ashika Umanga Umagiliya
不行,如果我有时间的话,我会重新考虑这个问题。我仍然想看看这是否可能。 - Derick Schoonbee
3个回答

1
你打算用什么语言来使用Qt?最近我不得不在Qt中构建一个简单的GUI,围绕着一个Python脚本,并使用了AOP Python包Aspyct来进行一些快速的前后操作。Qt是事件驱动编程,我建议先熟悉Qt的基础知识,许多东西与AOP风格的操作类似,然后找到一些适用于你计划在Qt中使用的语言的AOP库。

嗯...我认为自己已经超越了Qt的基础知识 ;) 最终对我有效的方法是通过使用CQRS来达到更高层次的抽象。在这个意义上,我通过不直接在方法级别上实现它来提高了“更高层次的关注点”。我仍然在想是否有没有Qt的方式/或者符合Qt精神的方式。我会看看Aspyct是否符合我的AOP预设。 - Derick Schoonbee
抱歉,我忘记添加了,我正在使用C++(gcc)。 - Derick Schoonbee

1

你可能考虑使用的另一个AOP框架是AspectC++。我已经尝试过它,似乎运行得非常好。他们甚至在网站上有一篇白皮书,介绍了如何将AspectC++与Qt一起使用。


0

如果你想在Qt框架内实现,可以看一下状态机框架。(并且摆脱异常 :)

然后你可以将Logger连接到状态改变事件上。


有趣的方法。我已经使用状态机,但主要是在“动态/变化的业务规则上下文”中使用,这也是它设计的目的。使用自定义事件可能会有一种方面化的感觉...但我追求的是动态方法或使用插槽作为切入点(如果有意义的话)。 - Derick Schoonbee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接