对软件设计来说,我倾向于让一个系统中的各个子模块满足高内聚,低耦合的特质.
如果耦合不可避免,那么我期望这种耦合一定是要通过一层统一的抽像接口来完成
的,没有约束的任由模块之间纵横交错,互相调用和影响,只会让模块的复杂度
变成乘方,依赖关系变强. 这种复杂度和依赖关系的增加既会带来更多的潜在bug风险
,也会增加日后代码维护的难度及工作量.
但在现实的开发中,却经常会发现想要达到这种 高内聚,低耦合,统一模块互操作接口
的 状态,会有很多的障碍.
比如,目前我正在设计的一个小型的语法分析器中涉及到了词法模块和语法模块, 出于开发
效率的考虑,词法模块我选择用lex, 语法模块我选择用yacc实现.一开始我期望词法和语法
模块之间作到足够独立,除了标准的yylex接口以外,不希望在词法和语法模块之间提供更
多的其他接口. 但是在实际实现中,却发现,有的动作如果仅仅通过词法模块来完成,需要
花费 10步甚至更多步的开销,而如果将这个动作的一部分放入语法模块,利用语法模块的
处理能力的话,可以将完成这个动作所需的处理减少至 三步, 四步,甚至更少. (一个直观的
例子就是,在Yacc编写的语法规则里加入对Lex中的 开始条件的设置,让Lex对同样的输入
流作出上下文相关的规则匹配. )
这种情况下, 是通过引入更多的处理逻辑来确保模块的独立性, 为以后的维护和扩展打下
更好的基础, 抑或是降低对模块依赖性的要求,让现有的代码更简洁有效,就需要软件设计
人员作出一定的权衡了.
具体到我目前面临的这个小型语法分析器的问题,我的选择是适当降低对模块依赖性的约束,
在不过多损失代码扩展性及维护性的基础上,将一部分动作挪到语法模块中实现.
如果耦合不可避免,那么我期望这种耦合一定是要通过一层统一的抽像接口来完成
的,没有约束的任由模块之间纵横交错,互相调用和影响,只会让模块的复杂度
变成乘方,依赖关系变强. 这种复杂度和依赖关系的增加既会带来更多的潜在bug风险
,也会增加日后代码维护的难度及工作量.
但在现实的开发中,却经常会发现想要达到这种 高内聚,低耦合,统一模块互操作接口
的 状态,会有很多的障碍.
比如,目前我正在设计的一个小型的语法分析器中涉及到了词法模块和语法模块, 出于开发
效率的考虑,词法模块我选择用lex, 语法模块我选择用yacc实现.一开始我期望词法和语法
模块之间作到足够独立,除了标准的yylex接口以外,不希望在词法和语法模块之间提供更
多的其他接口. 但是在实际实现中,却发现,有的动作如果仅仅通过词法模块来完成,需要
花费 10步甚至更多步的开销,而如果将这个动作的一部分放入语法模块,利用语法模块的
处理能力的话,可以将完成这个动作所需的处理减少至 三步, 四步,甚至更少. (一个直观的
例子就是,在Yacc编写的语法规则里加入对Lex中的 开始条件的设置,让Lex对同样的输入
流作出上下文相关的规则匹配. )
这种情况下, 是通过引入更多的处理逻辑来确保模块的独立性, 为以后的维护和扩展打下
更好的基础, 抑或是降低对模块依赖性的要求,让现有的代码更简洁有效,就需要软件设计
人员作出一定的权衡了.
具体到我目前面临的这个小型语法分析器的问题,我的选择是适当降低对模块依赖性的约束,
在不过多损失代码扩展性及维护性的基础上,将一部分动作挪到语法模块中实现.