标签:状态 actor 解析 获取 code 编译 失败 ext ali
思想概要
能把英语的Flyweight模式能翻译成“享元”说明译者具备极强的理解力和编程知识,因为它一下就说到了这个模式的重点和核心。享元模式就是要提供一个方法来共享对象,或者说为了尽量不创建多余的对象,比较常见的就是线程池技术吧。不过对我来说,最好有这个概念的是做编译器的时候,第一个版本的时候对每个从代码文件里读进来单词都创建对象来管理,代码量大的时候就傻眼了,程序因为对象太多而崩溃。
这个问题恰恰就是享元模式要解决的课题,即:程序存在大量重复对象的时候,尽量将同样对象中的共同部分剥离,创建为共享的对象。
上图比较清晰的看出来,java里的两个a在内存里实际上只有一个,通过这样的优化降低内存的使用量。
然而,享元模式面对的如果都是常量级别的对象,那他的运用范围会大打折扣,更多的时候我们需要考虑将更加一般的情况抽象出来,并用享元模式来优化。这里就涉及到享元模式里最重要的地方:内部状态和外部状态。
内部状态指的是对象里基本不发生变化的共有部分,它不会随着对象参与的运算而变化。而外部状态是在对象参与运算的过程中不断发生变化的,但是在运算结束后不用保存在对象中的那些信息。
我们通过一个例子来说明:如下图所示,当C语言解析器解析一段包含大量宏的代码时,我们常见的方法似乎就是各自创建临时宏调用的对象,它完整的包含了宏的名字,宏的结构和宏参数信息。
....
FUNC(5)
....
FUNC(7)
....
FUNC_NEW(8)
但是你会发现,C语言的宏是一个预先定义的结构,它必须是一致的。换句话说,FUNC(5)和FUNC(7)它们背后的宏的基本信息是一样的,只有参数5和7是不同的,这就符合内部状态和外部状态的划分定义。
实现方法
完成享元模式的逻辑分析后我们进入实现方法的讨论。
经过前面的介绍,我们几乎可以轻易的推断出,享元模式有一张哈希表(Map),它管理了已经创建的对象。当有新的创建要求到来时就启动查询,查询失败时才创建新对象,一句话,我们需要一个工厂类。
工厂负责查询并返回查询到的对象,或者负责生成新对象,它是整个结构的核心。其他的类保存了自己内部状态的信息,并在接收到外部状态(extrinsic state )时执行各自功能。
Macro macro = MacroFactory.createMacro("FUNC"); expand = macro.expand("5"); macro = MacroFactory.createMacro("FUNC"); expand = macro.expand("7"); macro = MacroFactory.createMacro("FUNC_NEW"); expand = macro.expand("8");
上面的代码揭示的是从工厂获取宏对象,然后设置参数后获取展开后的字符串,展开过程本身不影响宏对象在工厂中的内部状态,所以可以复用。
标签:状态 actor 解析 获取 code 编译 失败 ext ali
原文地址:https://www.cnblogs.com/mubawa/p/9640488.html