我使用 Open Close Principle(开闭原则)在算法开发上的案例

mosdeo

2020/10/12 发布于 编程 分类

文字内容
1. 我使用 Open-Close Principle (开闭原则) 在算法开发上的案例 林高远
2. 摘要 理想:不要重新发明轮子,尽可能复用已经完成的类。 现实:已经完成的类,只有一部份切合需要。 障碍:动手去修改已经完成的类,引起其他引用代码的错误,可谓牵一髮动全身。 放弃理想:不断重复类似功能的代码,使代码增加许多不必要的复杂程度。 朝理想改善:若能从头实践"对扩充开放、对修改封闭"的开闭原则(Open-Close Principle),有助于使旧代码在不变动的前提下,容易被复用。 我的实践:网上有许多开闭原则理论性的解释,与不实用的范例代码。本次视频将以 部門用到的回归(Regression)类分享在开发中的实际应用。
3. 听懂所需基础 ● 对面对对象(Object Oriented,OO)编程有基本了解 ○ ○ ○ 使用 Java、C# 的人,需要知道 interface 使用 C++ 的人,需要知道 abstract class、pure virtual function 看得懂 UML ■ 时间不够,我没有画得很 严谨,但尽可能把重点画到。
4. 最初的需求:多种回归方法(Method) SimpleLinearFitting() EulerBaseExpFitting() EulerBaseExpFitting2() XBaseExpFitting() PolynomialFitting() LogFitting()
5. 但是回归方法全都有状态,需要升级到 Class ● ● ● 必须先根据历史数据建模 建模后,重复推论 此处的状态就是模型参数 重复进入 初始化 推论 根据历史数据建模 新的 X = [ x0, x1, …, xn] 模型参数 f(x) 推论结果 Y = [ f(x0), f(x1), …, f(xn) ] 结束
6. 变化为:多种回归类(Class) SimpleLinearFitting PolynomialFitting public void ComputeModel(IEnumerable points) public double Inference(double inputX) public void ComputeModel(IEnumerable points) public double Inference(double inputX) EulerBaseExpFitting LogFitting public void ComputeModel(IEnumerable points) public double Inference(double inputX) public void ComputeModel(IEnumerable points) public double Inference(double inputX) EulerBaseExpFitting2 XBaseExpFitting public void ComputeModel(IEnumerable points) public double Inference(double inputX) public void ComputeModel(IEnumerable points) public double Inference(double inputX)
7. 下一个需求:回归类任意抽换、新增 Dev Story: 1. 2. 3. 4. 5. 原本没有实做那麽多种回归类 使用后,发现误差太大,不满意 又尝试了新的类 回归方法越做越多 造成麻烦(如图) 不断修改 应用回归程序 XXX.cs 引用 回归算法库 Regression.cs
8. 下一个需求:任意新增回归算法 希望是这样,有可能吗? 不能吧,因为不能把 A 类 instance 任意传给 B 类 reference TypeA a = new TypeB(); //会报错 直接套用 新回归算法类 应用回归程序 XXX.cs 引用 回归算法库 新回归算法类 Regression.cs class NewRegression
9. 下一个需求:回归类任意抽换、新增 可以! 以 interface 将所有回归类抽象化 回归算法库 Regression.cs 应用回归程序 XXX.cs 引用 <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) SimpleLinearFitting EulerBaseExpFitting 未来其他开发者可以自 行扩充的回归类 EulerBaseExpFitting2 XBaseExpFitting LogFitting PolynomialFitting
10. 下一个需求:回归类任意抽换、新增 回归算法库 Regression.cs 应用回归程序 XXX.cs 引用 <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) SimpleLinearFitting EulerBaseExpFitting 未来其他开发者可以自 行扩充的回归类 由 xxx.cs 的角度看, 这些回归类全都属于 IRegression, 可以在同一个 reference 上直接抽换。 EulerBaseExpFitting2 XBaseExpFitting LogFitting PolynomialFitting
11. 我在此第一个实践的 Open-Close Principle 对修改封闭(Close 原则) 回归算法库 Regression.cs 应用回归程序 XXX.cs 引用 <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) SimpleLinearFitting 未来其他开发者可以自 行扩充的回归类 对扩充开放(Open 原则) EulerBaseExpFitting EulerBaseExpFitting2 XBaseExpFitting LogFitting PolynomialFitting
12. 借由增加新的程式 码来扩充系统的功 能,而不是借由修 改原本已经存在的 程式码来扩充系统 的功能。 ref:http://teddy-chen-tw.blogspot.com/2011/12/2.html 对修改封闭(Close 原则) 类库 应用程序 XXX.cs 引用 <> pure_virtual() 未来其他开发者可以自 行扩充的类 对扩充开放(Open 原则)
13. 你以为 这样就没了?
14. 我如何选出好的回归算法? 两个指标: ● 皮尔森相关系数(Pearson correlation coefficient,PCCs) ○ ● 越大越好 均方误差(Mean Square Error,MSE) ○ 越小越好
15. 我指定回归表现指标,程序自动挑选 Class RegressionB 注意实心菱形! 图是 "a part of” 的关系 不是继承!(除C++外) 看代码辅助了解 Class RegressionA MSE or PCC s Evaluation public static IRegression AutoGetBestModel(IEnumerable points) <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) SimpleLinearFitting EulerBaseExpFitting EulerBaseExpFitting2 LogFitting XBaseExpFitting PolynomialFitting
16. 连挑选的指标,都抽换 Class RegressionB Class RegressionA ? Evaluation public static IRegression AutoGetBestModel(IEnumerable points, IRegressionBenchmarkStand benchmarkStand) <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) <> public double Score(IEnumerable expected, IEnumerable actual) public int Compare(double x, double y) SimpleLinearFitting EulerBaseExpFitting LogFitting EulerBaseExpFitting2 XBaseExpFitting PolynomialFitting 未来其他开发者可以自行 扩充的回归指标类 BestMSE BestPCCs
17. 我在此第二个实践的 Open-Close Principle 对修改封闭(Close 原则) 回归算法库 Regression.cs 应用回归程序 引用 XXX.cs Evaluation public static IRegression AutoGetBestModel(IEnumerable points, IRegressionBenchmarkStand benchmarkStand) <> public double Score(IEnumerable expected, IEnumerable actual) public int Compare(double x, double y) 对扩充开放 (Open 原则) 未来其他开发者可以自行 扩充的回归指标类 BestMSE BestPCCs
18. Overview UML 回归算法库 Regression.cs 应用回归程序 Evaluation 聚合(has a) public static IRegression AutoGetBestModel(IEnumerable points, IRegressionBenchmarkStand benchmarkStand) XXX.cs 组成(a part of) <> <> public void ComputeModel(IEnumerable points) public double Inference(double inputX) SimpleLinearFitting EulerBaseExpFitting2 EulerBaseExpFitting XBaseExpFitting LogFitting PolynomialFitting public double Score(IEnumerable expected, IEnumerable actual) public int Compare(double x, double y) 实现(Realization) 未来其他开发者可以自 行扩充的回归类 BestPCCs 未来其他开发者可以自行 扩充的回归指标类 BestMSE
19. 同时也是 Strategy Pattern 应用回归程序 XXX.cs Strategy Pattern in UML 图片来自 Wiki 回归算法库 Regression.cs Evaluation <> SimpleLinearFitting LogFitting EulerBaseExpFitting EulerBaseExpFitting2 XBaseExpFitting PolynomialFitting <> BestPCCs 未来其他开发者可以自 行扩充的回归类 BestMSE 未来其他开发者可以自行 扩充的回归指标类
20. END 感谢收看