Qt 中的面向方面编程

发布于 2024-09-12 01:47:26 字数 2252 浏览 2 评论 0原文

我正在尝试了解 AOP,一些 Qt 代码确实会有帮助。

来自 wikipedia 这里是一些示例代码(易于 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. :) ");
 }

然后是“方面化”:

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() (所有 QObject),我可以阻止调用(例如失败 OnBeforeTransfer)。

但是,如果我们随后将其进行下一次演变以获得更少且更清晰的代码,我想摆脱OnXXXX信号并连接Bank:: Transfer 插槽到 Security::transfer 插槽和 Logger::transfer。 Qt 中有动态的吗? :类似于调用槽的顺序以及阻止“槽链”中的下一次调用?

这整个上下文仍然可以被视为 AOP 对吗?我试图坚持“方法层面的切入点”,还是我完全偏离了重点?

I'm trying to get my head around AOP and some Qt Code would really help.

From wikipedia here is some sample code (easy for a Qt/C++ programmer to read):

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. :) ");
 }

And then "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 has signals and slots to decouple objects. But I still need to emit signals.

So: Can this be done with Qt or do I need some special framework/preprocessors as referenced in the wikipedia article?

I have a feeling that there must be some trick since Qt uses the Meta Object Compiler and some functionality might be "injected" with dynamic methods.... just spit-balling here ;)

Edit: To give a better context: I really like the dynamic aspects (power) of the Qt meta object with signals and slots and would like to keep a Qt feel to it. Thus, my idea is to make use of slots (or signals) as point cuts. For example:

If I define slot Bank::transfer(...) and then signal Bank::OnBeforeTranfer() and signal Bank::OnAfterTransfer(). If I then connect them to other aspects say Security::transfer() and Logger::transfer() (all QObjects) I can block calls (like fail OnBeforeTransfer).

But, if we then take it to the next evolution to get less and cleaner code I would like to get rid of the OnXXXX signals and connect the Bank::transfer slot to Security::transfer slot and Logger::transfer. Anything dynamic in Qt? : Like order of calling slots and and preventing next call in the "slot chain"?

This whole context can still be considered AOP right? I'm trying to stick to "method level point cuts" or am I totally beside the point here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮生面具三千个 2024-09-19 01:47:26

您打算使用什么语言的 Qt?我最近不得不在 Qt 中围绕 python 脚本构建一个简单的 GUI,并使用 AOP python 包 Aspyct 在前后做一些快速的事情。 Qt是事件驱动编程,我会说熟悉Qt基础知识,很多东西类似于AOP风格的操作,然后找到一些适合你计划使用Qt的语言的AOP库。

In what language are you planning to use Qt? I recently had to build a simple GUI in Qt around a python script and used the AOP python package Aspyct to do some quick before and after stuff. Qt is event-driven programming, I'd say get familiar with the Qt basics, many things are similar to AOP-style operations and then find some AOP libraries for the language you plan to use Qt in.

掀纱窥君容 2024-09-19 01:47:26

您可以考虑使用的另一个 AOP 框架是 AspectC++。我已经玩过它了,看起来效果很好。他们甚至在网站上有一份白皮书,描述如何将 AspectC++ 与 Qt 一起使用。

Another AOP framework you may consider using is AspectC++. I've played with it a bit and it seems to work quite well. They even have a whitepaper on the site that describes how AspectC++ can be used with Qt.

猫九 2024-09-19 01:47:26

如果您想留在 Qt 框架内,您可以查看 状态机框架。 (并消除异常:)

然后您可以将记录器连接到状态更改事件。

If you want to stay within the Qt framework, you could take a look at the State Machine Framework. (And get rid of the exceptions :)

Then you could just connect the Logger to state change events.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文