使用封装打破大Class的设计方法

Design Method to Break Large Class Using Encapsulation

我有一个大数据 class (D)(总共约 3000 行)。其用途可分为以下小节:

我已经把可视化作为一个单独的 class (V) 吐出来了。这主要是因为我可以将所有必要的可视化信息标记到 matlab figure(使用 setappdata),从而使可视化独立于 D。为了直接调用 V 我在 D.

中创建了一个包装器

我现在的问题是,这么大的class,我该如何进行拆分?我能想到的唯一三个选项是:

由于第一个和最后一个选项相当简单,我将举一个小例子说明第二个选项的含义:

我有一个主class:

classdef main < handle
    properties (SetAccess = private)
        analysis
    end

    methods
        function obj = main
           obj.analysis = analysis(obj);

           ...
        end

       ...  
    end
end

和子classes

classdef analysis < handle
    properties(SetAccess = private)
        parent
    end

    methods
        function obj = analysis(parent)
            obj.parent = parent;
        end

        ...
    end
end

这会以某种方式对方法进行分组。

语言是 Matlab 重要的情况。

我拆分代码的解决方案是确保将内容分解为合理的组件。在这种情况下,我假设您要存储很多变量。这里的关键是功能化一切,并使用封装进行有意义的抽象。您可以 运行 通过此清单:

  • 是否有某些函数是您始终使用一堆变量的?如果是这样,将它们分组到 class.
  • 是否有某些 class 您在稍作修改后反复使用的东西?如果是这样,请使用 class 继承。
  • 是否有某些 class 具有相似结构,但实现功能不同的东西?如果是这样,请使用抽象 classes.
  • 不要忘记使用局部函数并尽可能尝试矢量化。

对于您的情况,在信息有限的情况下,我会将您的工作流程分开如下。

  1. I/O操作,应该大概应该抽象Read/Write/Import/Create/Copy到DataReader下的方法或更多classes(如果代码比你描述的更复杂)class
  2. 分析 - 如果每个功能相似,则创建 class 继承。否则,将其放入 DataAnalyzer class 并相应地使用本地函数。
  3. Manipulation - 根据这些操作的优先级,为每个级别的操作创建不同级别的 类。可能在 DataManipulator class 下完成所有操作,并使用 getter 进行计算。
  4. Visualization - 类似于 Manipulation,也为每种类型的可视化封装到 classes 中。您可能可以将其全部封装在 DataVisualizer class 下,并为您正在绘制的每个图形设置一个 plot/print 函数。
  5. 关于Local/Private函数,尝试为简单的计算创建匿名函数,如果更复杂则为局部函数。如果您发现在多个地方使用本地函数,您可能需要重新设计 class,在某处输入函数句柄,或在子文件夹中使用私有函数。

也许如果你概述你正在做什么以及你想做的更详细的行动,我可以提供进一步的帮助。

编辑: 添加了一些代码来举例说明:

我假设您的数据在操作过程中没有被覆盖。如果是,只需将其存储在同一个变量中。如果 algo1 与 algo2 相同,那么您可以在 functions/classes 之间进行一些互连以进一步减少代码。您可以通过使用继承或从 algo1() 调用 algo2() 来互连。

script.m

D = DataReader.readData( 'file.txt' );
A = DataAnalyzer.analyzeData( D );
M = DataManipulator.manipData( D );
DataVisualizer.plotGraphs( M );

DataAnalyzer.m

classdef DataAnalyzer
    properties (SetAccess = private)
        ...
    end

    methods
        function obj = DataAnalyzer( D )
           ...
        end

        function A = analyzeData( obj.D )
           A.algo1 = obj.algo1(D);
           A.algo2 = obj.algo2(D);
           ...
        end

        function a = algo1( obj, D );
           ...(algo here)
        end
       ...  
    end
end