什么是反射

反射这个词的翻译挺令人费解的,总有种望文生义的感觉。

举个例子

我写了个摘要计算器,其中有如下代码:

1
2
3
4
5
6
if selected_algorithm == "SHA-512":
    algorithm = hashlib.sha512()
elif selected_algorithm == "SHA-256":
    algorithm = hashlib.sha256()
else:
    algorithm = hashlib.md5()

这段代码功能就是根据用户选择的摘要计算方式,创建对应的对象,算很典型的工厂方法。

但是我还是觉得有点麻烦,能不能更简洁?这就到了反射出场了:

1
2
3
4
if hasattr(hashlib, selected_algorithm):
    algorithm = getattr(hashlib, selected_algorithm)()
else:
    algorithm = hashlib.md5()

原本每增加一种摘要算法,要硬编码到程序中,新增一条判断分支;而使用反射机制,可以在运行时像改写源码一样,由选择的字符串反向找到对应的方法并调用。

那么古尔丹,代价是什么呢?代价仅仅是损失一些效率。 Java中有不少框架大量使用反射,比如知名的Spring

有一些解释反射机制的资料说反射可以无视封装性,强行访问类和对象的成员,我不认为这是一个好做法。如果需要访问,那么没必要设为私有或保护成员;如果必须这么做,最好思考一下架构是不是有问题,要不要更改架构了。

关于C++和反射

反正截至C++ 20标准依然没有添加这个机制,倒是有个关键字typeid有点反射的意味,可能在以后的标准里会添加吧。

综上所述,这个机制不是必须的,在某些应用场景确实会减少代码复杂性,按需使用即可。

编程领域,第一步看山是山,知道这个用法、机制;第二步看山不是山,知道什么时候不要用;第三步看山还是山,知道为什么用,也知道为什么不用,信手拈来,轻车熟路。