前言

以前最讨厌设计复杂方法调用, 就是那种需要一堆有逻辑规则的 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;
});

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

Fluent Builder 模式的更多相关文章

  1. Joshua Bloch错了? ——适当改变你的Builder模式实现

    注:这一系列都是小品文.它们偏重的并不是如何实现模式,而是一系列在模式实现,使用等众多方面绝对值得思考的问题.如果您仅仅希望知道一个模式该如何实现,那么整个系列都会让您失望.如果您希望更深入地了解各个 ...

  2. effective java 3th item2:考虑 builder 模式,当构造器参数过多的时候

    yiaz 读书笔记,翻译于 effective java 3th 英文版,可能有些地方有错误.欢迎指正. 静态工厂方法和构造器都有一个限制:当有许多参数的时候,它们不能很好的扩展. 比如试想下如下场景 ...

  3. Builder模式在Java中的应用

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...

  4. 创建型模式之Builder模式及实现

    建造者(Builder)模式 GOF给出的定义为:建造者模式是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 应用场景 使用建造者模式是为了将构建复杂对象的过程和它的部件 ...

  5. Builder模式

    原文来源于http://www.iteye.com/topic/71175 对于Builder模式很简单,但是一直想不明白为什么要这么设计,为什么要向builder要Product而不是向知道建造过程 ...

  6. Android Builder模式在开发中的应用

    最近在学习图片加载框架Glide的时候,被他精简的写法震惊了.一句话,就可以搞定. Glide.with(mContext) .load(url) .centerCrop() .placeholder ...

  7. JAVA Builder模式构建MAP/LIST的示例

    我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下: import j ...

  8. [转]C++设计模式:Builder模式

    Builder模式要解决的问题是,当我们要创建很复杂的对象时,有时候需要将复杂对象的创建过程和这个对象的表示分离开来.由于在每一步的构造过程中可以映入不同参数,所以步骤相同但是最后的对象却不一样.也就 ...

  9. Android设计模式源码解析之Builder模式

    https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/builder/mr. ...

  10. Builder模式(建造者模式)

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...

随机推荐

  1. microsoft office object版本对应offices版本

    1997年 Excel 97 Microsoft Excel 8.0 1999年 Excel 2000 Microsoft Excel 9.0 2001年 Excel XP Microsoft Exc ...

  2. 入门深度学习和TensorFlow

    入门深度学习和TensorFlow时,首先要确保掌握必要的先导知识,然后逐步通过理论和实践相结合的方式深入学习.以下是一个具体的引导例子以及后续的学习计划. 入门深度学习和TensorFlow 1. ...

  3. 自制基于simplefoc大功率驱动板想法的由来,同时欢迎有相同兴趣的F友一起来玩。。。

    前一阵子,偶然在B站上看了一个simplefoc的介绍视频,代码简洁.算法精妙让人佩服,更让人佩服的是:开源!遂!搜索之!不搜不知道一搜吓一跳,发现太OUT了,原来玩这个算法的人这么多,让我这个整天沉 ...

  4. Fiddler使用界面介绍-底部状态栏

    底部状态栏 1.Capturing抓包状态 Capturing:Fiddler正在抓包 空白:Fiddler停止抓包 2.All Processes抓取进程类型 All Processes:抓取所有进 ...

  5. argparse学习笔记

    argparse是 Python 的一个内置模块,用于编写用户友好的命令行接口.使用 argparse,你可以很容易地为 Python 脚本添加参数解析功能,使得脚本可以接受命令行选项和参数.学起来也 ...

  6. 【Vue】接口模块化处理

    在前端Vue项目中,接口会被统一放在一个目录中管理: 一个模块的所有接口放在一个JS文件中: 文件会导入封装好的请求方法,和动态绑定的接口地址 import request from '@/utils ...

  7. Jax框架的性能分析——性能分析可视化

    官方文档: https://jax.readthedocs.io/en/latest/profiling.html 将jax代码的性能文件写入到文件夹中,并给出上传第三方网站的链接生成(https:/ ...

  8. vue 识别\n \t 等字符(转载)

    使用.text(str)时,str中有"\n",但是页面显示却没有换行,需要在所在的 div添加属性 style="white-space: pre-line" ...

  9. Dolphinscheduler Docker部署全攻略

    作者| 陈逸飞 Docker部署的目的是在容器中快速启动部署Apache Dolphinscheduler服务. 先决条件 docker-compose docker 使用容器单机部署Dolphins ...

  10. SMU Autumn 2023 Round 1(Div.1)

    SMU Autumn 2023 Round 1(Div.1) A. Set or Decrease(枚举) 题意就是你可以进行两种操作,将\(a_i-1\)或者令\(a_i\)等于\(a_j\),然后 ...