我试图理解面向切面编程(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吗?我试图坚持“方法级切入点”,还是完全离题了?