【问题标题】:What design pattern(s) would fit to LOAD-CONVERT-WRITE like scenarios?什么样的设计模式适合 LOAD-CONVERT-WRITE 之类的场景?
【发布时间】:2012-10-16 12:15:33
【问题描述】:

我不想重新发明轮子。

是否有适合以下工作流程的设计模式或模式。想法是有一个适合所有人的通用解决方案:加载数据-->转换它-->写入转换后的

喜欢:

(1) LOAD DATA : 从 DataSource 加载数据并生成一个 IEnumerable

(2) COVNERT LOADED DATA - 遍历加载的数据,并根据转换逻辑将它们转换为 TConverted 类型

(3) WRITE CONVERTED DATA - 遍历 IEnumerable 并将每个项目写入 .txt 文件

【问题讨论】:

    标签: c# .net design-patterns


    【解决方案1】:

    我相信 Pipelines pattern 在 MSDN 上有一个很好的 C# .NET 4.0 implementation

    这个想法是提取阶段,并为每个阶段安排一个 TPL 的 Task 的新实例,然后通过 BlockingCollection<T> 实例将所有实例捆绑在一起作为中间缓存。

    还值得注意的是,引用的 MSDN 论文中提到的 BlockingCollection.GetConsumingEnumerable() 会根据需要返回 IEnumerable<T>

    一般流程示例:

    【讨论】:

    • 我不明白为什么我需要并行任务?你可以解释吗?对我来说,这听起来像是按顺序进行的操作......
    • 您说返回的数据是IEnumerable,因此如果您将按部分读出并推送到转换,那么您可以加快整个过程,因此当您在转换阶段读取下一个数据部分时,前一个数据部分,所以这将加速巨大的数据集处理,因此将成为不同数据源的通用解决方案
    • 有道理...当我从 SQL Db 读取这些大数据时,它实际上是否算数。使用 LINQ 查询? (或者只有当我使用 SqlDataReader 阅读时才算数?)
    【解决方案2】:

    “模板方法”模式可以帮助您构建一个通用框架,该框架可用于针对不同类型的数据实现此过程。会有一个像这样的抽象基类:

    public abstract class ETLProcess {
        public final runETL() {
            IEnumerable rawData = extract();
            IEnumerable tranformedData = transform(rawData);
            load(transformedData);
        }
    
        protected abstract IEnumerable extract();
        protected abstract IEnumerable transform(IEnumerable rawData);
        protected abstract load(IEnumerable transformedData);
    }
    

    然后你可以通过扩展ETLProcess类来实现不同类型数据的处理。这种模式的优点是您可以在抽象类中定义您的流程,而在具体类中定义各个步骤。您可以将通用代码、通用错误处理等放在基类中。

    【讨论】:

      【解决方案3】:

      我相信您正在寻找Adapter 模式。我经常将转换视为既不偏向客户也不偏向适应者的中间阶层。包装器的想法并不总是“感觉”很抽象。然而,最好还是编写专门设计的类,以使传入数据适应客户的期望。如果您觉得它违反了您的抽象,请考虑创建基类或接口,并针对传入数据的细节实现它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-01
        • 2023-04-07
        • 2019-11-30
        相关资源
        最近更新 更多