话题的起因

最为近日在复习一些知识,准备复习设计模式。 关于设计模式的书,有很多。Java 的 Ruby 的 PHP 的,唯独没有 《Python 设计模式》

在群里发问,一起讨论下为何没有 《Python 设计模式》。 其中的意思,便是讨论 Python 与其他语言的差异。

对于问题,我们没有做太详细或是深入的讨论,转而其他方面的讨论。

AOP

AOP(Aspect-Oriented Programming,面向侧面编程 面向切面编程,感谢MarkNV 指出错误。)

Aspect 是一种新的模块化机制,它描述的是分散在程序内部的 横切关注点(crosscutting concern)

所谓 横切关注点 是分散在程序代码内部(例如被虚函数分散到各个没关系的函数中),难以被类或函数捕捉的代码。

比如 Java Spring 中的 Logging:

if (!isUserAuthorised(user, fromAcc)) {
    logger.info("User has no permission.");
    throw new UnauthorisedUserException();
}
if (fromAcc.getBalance() < amount) {
    logger.info("Insufficient funds.");
    throw new InsufficientFundsException();
}

上面的代码(Java)中的 logger 即是横切关注点,它可能会贯穿整个程序,但却无法使用一个类或者一个函数将其抽离出来。

而 Python 提供了 with 和 decorator 的方式,用过这个方式,可以将横切关注点抽离出来:

from contextlib improt contextmanager

@contextmanager
def login_required():
    logger.info('logined checked')
    try:
        yield
    except AccessException:
        logger.info('access error')
    finally:
        logger.info('somethings.')

@login_required
def handler():
    return 'balabala'

条理化 Decorator

Python 中提供的 decorator 实现的方式是这样的:

def login_required(handler):
    def check():
        if not user.authenticated:
            raise Exception('You have not permissions')
        return handler
    return check

Python 还提供另一种方式来实现 decorator:

class login_required:

    def __init__(self, handler):
        self.handler = handler

    def __call__(self):
        if not user.authenticated:
            raise Exception('You have not permissions')
        return self.handler

使用 类 的方式可以使得 decorator 更有条理。