最近工作比较忙,很久没写东西了,今天突然有再写一写的冲动,于是就有了这篇^_^

    三个月之前,我曾经写了一篇关于算术表达式求值的文章,当时是单纯从算法的角度考虑整个问题的,而没有考虑到软件的扩展性,三个月以后,
我重新考虑了这个问题,怎么让这个微型的程序具备扩展性呢?空闲时间看了不少 SharpDevelop 的源码,对其中的插件实现机制当然会有一定印
象,那么何不用插件的形式来实现下这个程序呢?这样就可以在将来需要新的运算法则时方便地扩展,而不必更改已经存在的程序,那么就简单地设
计一下吧(其实我不太喜欢使用“设计”一词的,因为貌似这个词已经泛滥了,但是此处貌似也没有别的词来代替)。

    废话了这一通,不知道各位看客有没有已经想吐了,那就开始吧。首先是弄个接口出来吧:

一次重构 (算术表达式求值问题)
一次重构 (算术表达式求值问题)// Output.cs
一次重构 (算术表达式求值问题)
using System;
一次重构 (算术表达式求值问题)
  // IExpressionCalculator.cs
  using System;
一次重构 (算术表达式求值问题)
using System.Collections.Generic;
一次重构 (算术表达式求值问题)

算法问题早写过了(参考 使用传统算法进行表达式求值), 这里就不重复了. 现在实现一个简单的算子, 也就是实现 接口 IExpressionCalculator
这里就实现一个加法运算吧

一次重构 (算术表达式求值问题)// AddCalculatorCodon.cs
一次重构 (算术表达式求值问题)
using System;
一次重构 (算术表达式求值问题)
using System.Collections.Generic;
一次重构 (算术表达式求值问题)
using CnBlogs.Youzai.CalculatorCodonInterface;
一次重构 (算术表达式求值问题)

这里的 Priority 设置需要注意, 相同优先级的运算符应该设置为相同, 还有要留有一定的余地, 比如加减可以设为 0,乘除为10, 这样就可以确保将来
扩展时不至没有可用的 Priority. 其他的运算实现方法相似, 这里就不写了。把每一个算子编译成单独的程序集,然后用反射的方式加载并实例化。当
然也可以把类似的运算编译在同一个程序集里。

下面是程序集加载和算子实例化以及算法实现,不多解释,直接给出代码好了。

一次重构 (算术表达式求值问题)// CalculatorManager.cs
一次重构 (算术表达式求值问题)
using System;
一次重构 (算术表达式求值问题)
using System.IO;
一次重构 (算术表达式求值问题)
using System.Reflection;
一次重构 (算术表达式求值问题)
using System.Collections.Generic;
一次重构 (算术表达式求值问题)
using CnBlogs.Youzai.CalculatorCodonInterface;
一次重构 (算术表达式求值问题)

    CalculatorManager 是一个 Singleton 类,使用应该方便的,UI 实现起来很简单,这里就不写了。

    将来有新的运算需要添加时,只需要实现 IExpressionCalculator 接口,编译成单独的程序集,所以放在 .\AddIns\目录下面就可以了,
程序启动时会自动搜索
现在你就有一个可扩展的表达式求值运算器了。一次重构 (算术表达式求值问题)

一次重构 (算术表达式求值问题)

一次重构 (算术表达式求值问题)

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-09-18
  • 2022-02-07
  • 2022-12-23
  • 2021-12-09
猜你喜欢
  • 2021-06-27
  • 2021-11-05
  • 2021-09-07
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案