zoukankan      html  css  js  c++  java
  • Fluent Builder 模式

    前言

    以前最讨厌设计复杂方法调用, 就是那种需要一堆有逻辑规则的 config 作为参数的方法. 

    这种 config 通常是一个大对象, 有许多 property, property 之间有存在一些逻辑, 比如当 property A 是什么的时候 B 必须也是什么.

    如果单侧不管它, 那么调用方法的人就会很幸苦, 一直到 runtime 才会报错.

    Fluent Builder 模式

    Fluent Builder 模式就是用来有条有理的创建复杂对象的. 比如上面说到的 config.

    很多地方都可以看到它的影子.

    EF Core 和 OData 都用了这个方式来创建 model.

    fluentvalidation 也是用了这个方式来创建 validation rules

    如何实现

    参考: Fluent Builder模式简介

    其内部原理就是通过几个小的 builder, 每一个 builder 负责一部分创建. 然后串起来.

    每一个小 builder 就可以通过方法, 去声明类型, 和限制调用顺序等.

    虽然它不能 100% 解决使用者调用错误的问题, 但是已经非常多了. 

    在设计方法调用的时候, 我们不可以认为使用者是开发人员就顺便的做, 应该要尽可能让调用简单, 智能, 有类型推到.

    before 

    builder.HasPrincipalProperty(e => e.ProductName, e => e.Color.Product.Name, conditionalInfo: new RedundancyExpressionVersionConditionalInfo<Size>
    {
        WhereExpression = e => e.Type == SizeType.TypeA,
        WhenNoInCondition = WhenNoInCondition.AutomaticallySetToNull
    });
    builder.HasPrincipalProperty(e => e.ProductId, e => e.Color.Product.Id, conditionalInfo: new RedundancyExpressionVersionConditionalInfo<Size>
    {
        WhereExpression = e => e.Type == SizeType.TypeA,
        WhenNoInCondition = WhenNoInCondition.AutomaticallySetToNull
    });
    builder.HasPrincipalProperty(e => e.Age, e => e.Color.Product.Age, conditionalInfo: new RedundancyExpressionVersionConditionalInfo<Size>
    {
        WhereExpression = e => e.Type == SizeType.TypeA,
        WhenNoInCondition = WhenNoInCondition.AutomaticallySetToNull
    });

    after

    builder.HasPrincipalProperty()
        .Relation(e => e.Color.Product)
        .PropertyMap(e => e.ProductName, e => e.Name)
        .PropertyMap(e => e.ProductAge, e => e.Age)
        .PropertyMap(e => e.ProductId, e => e.Id)
        .Conditional(condition =>
        {
            condition.WhereExpression = e => e.Type == SizeType.TypeA;
            condition.WhenNoInCondition = WhenNoInCondition.SetValueManually;
        });

    这个例子里面有点复杂, 不适合用作教学, 看看调用自己揣摩一下就好.

  • 相关阅读:
    从小知识开始练习
    shell的基本语法
    shell的一些简单用法
    HTML 父元素与子元素之间的margin-top问题
    HTML input文本框设置和移除默认值
    c# winform进入窗口后在文本框里的默认焦点
    c#面向对象基础 重写、虚方法、抽象类
    c#面向对象基础 封装、继承
    c#面向对象基础 静态成员、构造函数、命名空间与类库
    c#面向对象基础 类、方法、方法重载
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15768012.html
Copyright © 2011-2022 走看看