Fluent Builder 模式
前言
以前最讨厌设计复杂方法调用, 就是那种需要一堆有逻辑规则的 config 作为参数的方法.
这种 config 通常是一个大对象, 有许多 property, property 之间有存在一些逻辑, 比如当 property A 是什么的时候 B 必须也是什么.
如果不管它, 那么调用方法的人就会很幸苦, 一直到 runtime 才会报错.
Fluent Builder 模式
Fluent Builder 模式就是用来有条有理的创建复杂对象的. 比如上面说到的 config.
很多地方都可以看到它的影子.
EF Core 和 OData 都用了这个方式来创建 model.

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

如何实现
其内部原理就是通过几个小的 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 模式的更多相关文章
- Joshua Bloch错了? ——适当改变你的Builder模式实现
注:这一系列都是小品文.它们偏重的并不是如何实现模式,而是一系列在模式实现,使用等众多方面绝对值得思考的问题.如果您仅仅希望知道一个模式该如何实现,那么整个系列都会让您失望.如果您希望更深入地了解各个 ...
- effective java 3th item2:考虑 builder 模式,当构造器参数过多的时候
yiaz 读书笔记,翻译于 effective java 3th 英文版,可能有些地方有错误.欢迎指正. 静态工厂方法和构造器都有一个限制:当有许多参数的时候,它们不能很好的扩展. 比如试想下如下场景 ...
- Builder模式在Java中的应用
在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...
- 创建型模式之Builder模式及实现
建造者(Builder)模式 GOF给出的定义为:建造者模式是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 应用场景 使用建造者模式是为了将构建复杂对象的过程和它的部件 ...
- Builder模式
原文来源于http://www.iteye.com/topic/71175 对于Builder模式很简单,但是一直想不明白为什么要这么设计,为什么要向builder要Product而不是向知道建造过程 ...
- Android Builder模式在开发中的应用
最近在学习图片加载框架Glide的时候,被他精简的写法震惊了.一句话,就可以搞定. Glide.with(mContext) .load(url) .centerCrop() .placeholder ...
- JAVA Builder模式构建MAP/LIST的示例
我们在构建一个MAP时,要不停的调用put,有时候看着觉得很麻烦,刚好,看了下builder模式,觉得这思路不错,于是乎,照着用builder模式写了一个构建MAP的示例,代码如下: import j ...
- [转]C++设计模式:Builder模式
Builder模式要解决的问题是,当我们要创建很复杂的对象时,有时候需要将复杂对象的创建过程和这个对象的表示分离开来.由于在每一步的构造过程中可以映入不同参数,所以步骤相同但是最后的对象却不一样.也就 ...
- Android设计模式源码解析之Builder模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/builder/mr. ...
- Builder模式(建造者模式)
在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...
随机推荐
- UE MultiLineTraceByChannel函数返回只有一个对象的问题
问题描述 MultiLineTraceByChannel,看函数名字是返回射线检测到的所有对象,实际使用过程中,发现返回的数组中只又一个对象. Multi Line Trace by Channel ...
- 解读GaussDB(for MySQL)灵活多维的二级分区表策略
本文分享自华为云社区<GaussDB(for MySQL)创新特性:灵活多维的二级分区表策略>,作者:GaussDB 数据库. 背景介绍 分区表及二级分区表的功能,可以让数据库更加有效地管 ...
- .NET 轻量级 命令行工具 CSharpRepl
前言 当我们需要快速测试代码片段时,常见的做法是启动Visual Studio或使用在线代码编辑器.然而,Visual Studio的启动可能较为缓慢且占用较多系统资源,而在线编辑器则可能遇到语法支持 ...
- 缓存框架 Caffeine 的可视化探索与实践
作者:vivo 互联网服务器团队- Wang Zhi Caffeine 作为一个高性能的缓存框架而被大量使用.本文基于Caffeine已有的基础进行定制化开发实现可视化功能. 一.背景 Caffei ...
- hbuilderx打正式包所需的私钥证书的创建方法
现在使用uniapp作为底层框架来开发app应用已经成为了很多公司的事实标准,而uniapp的开发工具hbuilderx云打包的时候,需要私钥证书和证书profile文件. 而且还需要将打包好的ipa ...
- k8s 环境搭建(2)
安装docker组件 配置本地源或者自带的网络源2选1 1.切换镜像源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce ...
- 常用的adb命令(重要)
常用的adb命令(重要)
- Snipaste截图工具-测试工程师强推
Snipaste主要功能是截图和贴图,网上下载直接安装即可. 个人认为Snipaste比其它截图好用的点: 快捷键简单.Snipaste只需按F1截图,不会和其它截图工具的快捷键冲突 贴图功能.贴图功 ...
- 对比python学julia(第一章)--(第二节)似曾相识燕归来
Julia和python一样,都是跨平台开源语言,而且都是动态语言,所以毫无疑问,需要运行时支撑.很简单,到官网去下载julia(https://julialang.org/downloads/).和 ...
- 【TypeScript】02 面向对象
[联合类型] 联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值. 注意:只能赋值指定的类型,如果赋值其它类型就会报错. var val:strin ...